1. 程式人生 > >禁止在堆中例項化的類【1】

禁止在堆中例項化的類【1】

    設計一個禁止在堆中例項化的類,需要過載operator new和operator delete,並將其設為private。當然,也不是沒有破解的方法,那就是placement new。

// 禁止在堆中例項化物件?
// 在堆中例項化物件,需要使用new和delete,因此如果想要禁止,那就過載...
// (1)禁止使用者在堆中例項化物件:將new和delete過載為私有或保護函式
// (2)連類內部的成員函式都不能用new和delete:過載new和delete為私有成員函式,但是隻宣告,不實現

#include <iostream>
#include <new>
using namespace std;

// A:使用者不能用new,自己可以用new
class A
{
public:
    A(){cout<<"A:: ctor"<<endl;}
    ~A(){cout<<"~A::decon"<<endl;}
    static void use_new()
    {
        A*p=new A;
        cout<<"use_new"<<endl;
        delete p;
        p=0;
    }
    void print(){cout<<"It is A"<<endl;}
private:
    void *operator new(size_t){}
    void operator delete(void *p){}  
    
};

// B:使用者不能用new,自己也不可以用new
class B
{
public:
    B(){cout<<"B:: ctor"<<endl;}
    ~B(){cout<<"~B::decon"<<endl;}
    void print(){cout<<"It is B"<<endl;}
    static void use_new()   // 這個函式永遠不可使用!除非實現operator new和operator delete
    {
        B*p=new B;
        cout<<"use_new"<<endl;
        delete p;
        p=0;
   }
private:
    void *operator new(size_t);
    void operator delete(void *p);  
    
};

int main()
{
    {
        A a;
        B b;
        A::use_new();    // use_new成員函式使用了new/delete,類A可以在成員函式中使用new和delete
 //       B::use_new();  // 如果去掉註釋,在連結時會報錯
    }
    cout<<endl<<endl;

    {
        cout<<"0        ";
        char *cp = new char [sizeof(A)];
        cout<<"1        ";
        A *ap=::new((void*)cp) A;  // placement new! 用(::new),否則系統會首先呼叫過載的那個new.
                                   // placement new繞過了operator new,可以在任意位置呼叫建構函式...!
        cout<<"2        ";
        ap->print();
        cout<<"3        ";
        ap->~A();                  // 顯式呼叫解構函式別忘記。
        cout<<"4        ";
        delete cp;
        cout<<endl;
    }

    return 0;
}

run:
[email protected]:~$ g++ stackonly.cpp -o stackonly
[email protected]:~$ ./stackonly 
A:: ctor
B:: ctor
A:: ctor
use_new
~A::decon
~B::decon
~A::decon


0        1        A:: ctor
2        It is A
3        ~A::decon
4        
[email protected]:~$ 



相關推薦

禁止例項1

    設計一個禁止在堆中例項化的類,需要過載operator new和operator delete,並將其設為private。當然,也不是沒有破解的方法,那就是placement new。 // 禁止在堆中例項化物件? // 在堆中例項化物件,需要使用new和dele

虛幻4的程式化生成1程式化生成河流。

給自己立了很多flag,由於時間原因很多系列都還在寫,算是循序漸進的總結。在程式化生成系列裡,將會有如下記述: 【1】程式化生成河流 主要內容有@1 shader的自動調整(如河流的深淺,河水的波濤程

解釋C++例項的指標型別的new

Intarray * parray = new Intarray();//括號 int * parray = new int(); 兩個都不止是申明,已經初始化了。 第一句是建立(例項化)了一個Intarrya的物件,指標parray指向它。 第二句是建立(分配了)了int型

例項,怎麼限制只能在或棧分配!

昨天一個同學去網易面試C++研發,問到了這麼一個問題:如何限制一個類物件只在棧(堆)上分配空間? 一般情況下,編寫一個類,是可以在棧或者堆分配空間。但有些時候,你想編寫一個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想想,其實也是可以滴。 在C

Spring框架使用java反射無法例項,使用ReflectionUtils.findMethod

Spring框架中的反射問題 問題描述 在spring的框架的專案中,使用java的反射去例項化一個service類的時候獲取不到該類的物件. try { Class cla = Class.forName(apiName); //資料庫

Unity3d修煉之路:遊戲開發,3d數學知識的練習1(不斷更新.......)

turn tor rdo pre 長度 scrip 縮放 unity3d float #pragma strict public var m_pA : Vector3 = new Vector3(2.0f, 4.0f, 0.0f); public var m_pB :

1000行代碼徒手寫正則表達式引擎1--JAVA正則表達式的使用

基礎上 unicode 要求 [1] 分配 find 通過 images char 簡介: 本文是系列博客的第一篇,主要講解和分析正則表達式規則以及JAVA中原生正則表達式引擎的使用。在後續的文章中會涉及基於NFA的正則表達式引擎內部的工作原理,並在此基礎上用1000行左右

#Java#1呼叫父被重寫的方法

一、程式碼 package com.atguigu.exer1; //========== Son =================== public class Son extends Father { public String str = "

JVM規範初始的5種情況(有且僅有)

類從被載入到虛擬機器記憶體中開始,到卸載出記憶體為止,它的整個生命週期包括:載入、驗證、準備、解析、初始化、使用和解除安裝 7個階段。其中驗證、準備、解析3個部分統稱為連線。 載入、驗證、準備、初始化和解除安裝這5個階段的順序是確定的,類的載入過程必須按照這種順序按部就班的

建立java例項物件

建立java類並例項化類物件例一1.面向物件的程式設計關注於類的設計2.設計類實際上就是設計類的成員3.基本的類的成員,屬性(成員變數)&方法 面向物件思想的落地法則一:1.設計類,並設計類的成員(成員變數&成員方法)2.通過類,來建立類的物件(也稱作類的例項化) public cl

js版 劍指offer1陣列重複的數字

題目描述: 在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度為7的陣列{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數

python:例項物件時提示“TypeError: Employee() takes no arguments”的解決方法

最近開始學習python,學習面向物件的知識時遇到一個問題 在建立例項物件時提示“TypeError: Employee() takes no arguments”,百度翻譯了一下,意思是這個類的建構函式不接受引數 找了半天實在不理解哪裡出問題了,明明都在"_

1000行程式碼徒手寫正則表示式引擎1--JAVA正則表示式的使用

簡介: 本文是系列部落格的第一篇,主要講解和分析正則表示式規則以及JAVA中原生正則表示式引擎的使用。在後續的文章中會涉及基於NFA的正則表示式引擎內部的工作原理,並在此基礎上用1000行左右的JAVA程式碼,實現一個支援常用功能的正則表示式引擎。它支援貪婪匹配和懶惰匹配;支援零寬度字元(如“\b”, “\B

C# 反射通過例項

在面向物件程式設計的時候,會遇到這樣的問題,一個父類有多個子類,需要建立一個父類的物件,再後面根據條件去把該物件例項化具體的某個子類,然後進行操作。當然用if else 或者switch來做也可以,但是後期擴充套件性不好,特別是要把這些類封裝成dll提供給被人用

php實現例項後自動進行錯誤以及異常處理(簡易版)

<?php class App { public function __construct() { /* * ini_set 設定配置項 * display_errors 是否在頁面顯示錯誤資訊 *

《物件建立過程 例項的順序》摘自《Thinking in JAVA》

最近一直在看《Thinking In JAVA》,裡面一些知識點自己平日裡還真沒有注意過: 譬如這部分:在例項化物件的過程,物件的各部分的初始化順序: 總結一下物件的建立過程,假如有個名為Dog的類: 1.即使沒有顯示的使用Static關鍵字,構造器實際上也是靜態方法,

SSH框架實現Struts21 最簡單完整例項- IDEA

工具IDEA  1.首先去Struts2官網下載jar包 http://struts.apache.org/download.cgi#struts2512 這幾個是常用的。 找個資料夾存放這些jar包然後 在IDEA新建工程,依次選擇。然後OK 可以看到IDEA在sr

機器學習層次聚演算法-1HCA(Hierarchical Clustering Alg)的原理講解 + 示例展示數學求解過程

層次聚類(Hierarchical Clustering)是聚類演算法的一種,通過計算不同類別資料點間的相似度來建立一棵有層次的巢狀聚類樹。在聚類樹中,不同類別的原始資料點是樹的最低層,樹的頂層是一個聚類的根節點。建立聚類樹有自下而上合併和自上而下分裂兩種方法,本篇文章介紹合併方法。層次聚類的合併演算法層次聚

spring ioc例項bean以及依賴注入bean和基本型別屬性簡單實現方案

Spring兩個重要特性IOC和AOP,本文中簡單實現bean的建立以及屬性依賴注入。 實現步驟如下: 1、通過dom4j解析bean.xml檔案,將bean物件以及依賴屬性裝入List。 2、遍歷list,通過反射機制例項化物件。 3、遍歷list,通過反射呼叫bean裡

自頂向下分析Binder1—— Binder例項

一個Binder例項 我們Binder的學習將從下面的一個例項開始。根據Android文件中的描述,建立一個Binder服務主要包括如下3步: 下面具體看一下在eclipse中是如何開發一個Binder應用的。 第