這個是個面試題,不知道的時候確實會一比較懵;那麼具體如何實現呢?
棧和堆這兩種內存的使用想象大家都瞭解吧,棧一般是靜態建立一個對象的時候會有編譯器自動創建,而堆是需要調用new來達到目的的。
首先若是不能調用new,那麼就無法在堆上生成對象了,那麼...,我們重載一下operator new以及operator delete 置爲私有部分,類外就無法調用new來在堆上生成對象了,所以只能在棧上生成對象了...代碼如下:
class C
{
public:
C()
{
cout << "C()" << endl;
}
~C()
{
cout << "~C()" << endl;
}
private:
void* operator new(size_t);
void operator delete(void *);
};
void Test3()
{
//C *ptr = new C();
C c;
}
只在棧上生成對象是解決了,那麼要想只在堆上生成對象的話,意思就是隻能通過new來生成對象了。我們可以將析構函數設置爲私有的,這樣類外使用靜態方法創建對象的時候就會報錯,這樣可以達到目的,於此同時需要自己提供一個接口,用於釋放對象。
但是我們知道私有函數在繼承的時候是無法直接在派生類中直接調用的(而且在delete的時候會調用析構函數,這個時候也是不行的...),那麼這樣的話我們就考慮到了將析構函數設置爲保護的,因爲保護屬性是轉爲繼承而生的,這樣就可以解決上述問題而且滿足要求。
class B
{ //只在堆上創建對象,聲明爲protected的無法繼承
public:
static B* Create()
{
return new B();
}
void Destroy()
{
delete this;
}
protected:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
void Test2()
{
//B b;
B *pa = B::Create();
pa->Destroy();
}
這裏我將構造函數設置爲保護成員了,然後通過靜態成員函數來完成對象的構造,通過專門的成員函數釋放對象。