C++如何只能在堆上或棧上生成對象

#include <iostream>
using namespace std;

//只能在棧上構造對象的實現:即不能調用new來在堆上構造對象,調用new其會調用operator new(),
//所以只要顯示定義重載一下operator new() operator delete()操作符設爲私有部分
//類外就無法調用new/delete在堆上建立釋放對象了。
class B
{
public:
	B()
	{
		cout<<"B()"<<endl;
	}
	~B()
	{
		cout<<"~B()"<<endl;
	}

private:  //顯示定義設爲私有權限
	void* operator new(size_t);
	void operator delete(void*);
public:
	int _b;
}; 
void test1()
{
	B b;
	//B* pb=new B();  //編譯錯誤
}

//只能在堆上構造對象,不能在棧上:即不能靜態由編譯器直接創造對象則只需將構造函數
//與析構函數設爲私有的,即類外就不能在棧上自動構造對象(又由於考慮到繼承:派生類不能訪問基類私有函數,
//則將造成派生類中的父類成員不能成功調用其父類構造函數與析構函數,所以要將構造函數與析構設爲protected)
//最後提供接口實現用new生成對象,delete釋放對象
class C
{
public:
	static C* Create()  //用靜態函數原因:還沒有類對象只能用類調用靜態函數創造對象
	{
		return new C();   //類內new原因new過程也會調用構造函數,而構造函數現已類外不能訪問
	}
	void Destroy()//不用靜態函數原因:現已存在對象,可用對象調用此函數
	{
		delete this;   //類內delete與上相同原因,析構函數權限爲保護,類外不能訪問
	}
protected:  //保護權限考慮繼承
	C()
	{
		cout<<"C()"<<endl;
	}
	~C()
	{
		cout<<"~C()"<<endl;
	}
public:
	int _c;
};
void test2()
{
	//C c;
	//C* c=new C();
	C* c=C::Create();
	c->Destroy();
}
int main()
{
	test1();
	test2();
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章