禁止在堆中例項化的類【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]:~$