C++中兩種建立對象的方式

來源:互聯網
上載者:User

標籤:namespace   刪除   -o   建立   最好   cout   cpp   測試   需要   

 

 在C++中,為了讓某個類只能通過new來建立(即如果直接建立對象,編譯器將報錯),應該()

正確答案: B   你的答案: D (錯誤)
將建構函式設為私人
將解構函式設為私人
將建構函式和解構函式均設為私人
沒有辦法能做到

 

 

當時沒有多想,覺得不太可能。事後想起來才發現這很容易做到,實質上還是記憶體管理的問題。

 只能做堆上建立對象 

在C++中,類的建立分為兩種。一種是靜態建立,即直接建立對象;另一種是動態建立對象,即通過 new 建立,如 T *t = new T。要想正確回答上題,就必須知道這兩種建立方式的區別。

1 靜態建立

由編譯器在棧中為對象分配記憶體,通過移動棧頂指標獲得合適大小的空間,然後調用對象的建構函式產生對象。

2 動態建立

通過new在堆中建立對象。這個過程分為兩步:首先在堆中找到合適大小的空間並分配,然後調用對象的建構函式產生對象。

 

因為兩者都需要調用對象的建構函式,所以通過將建構函式私人化的做法是行不通的。那麼還有其他辦法嗎?這是就需要瞭解靜態建立的另一個特點了。

編譯器在為類對象分配棧空間時,會先檢查類的解構函式的訪問性,其實不光是解構函式,只要是非靜態函數,編譯器都會進行檢查。如果類的解構函式是私人的,則編譯器不會在棧空間上為類對象分配記憶體。

所以我們只需要將解構函式私人化就可以組織直接建立對象了。由於棧的建立和釋放都需要由系統完成的,所以若是無法調用構造或者解構函式,自然會報錯。

當然為了我們能夠正確釋放動態建立的對象,我們必須提供一個公有函數,該函數的唯一功能就是刪除對象本身

 測試代碼如下:

 

#include<iostream>using namespace std;class test{private:~test(){ cout << "test destroy" << endl; }public:void destroy(){delete this;}};int main(){//test p;//編譯器報錯test::~test()不可訪問test *p = new test;p->destroy();}

 

 

只能在棧上建立對象 既然可以做到只在堆上建立對象,同樣的我們可以只在棧上建立對象。其實理解了這個理念,不難想到我們只需要 讓new操作符無法使用即可,要做到這件事,我們可以將 new操作符重載並設定為私人訪問即可。是不是很巧妙的方法~

 

重載new的同時最好重載delete

 

#include<iostream>using namespace std;class test{private:void* operator new(size_t t){}void operator delete(void* ptr){}public:~test(){cout << "test destroy" << endl;}};int main(){//test *A = new test;//編譯器報錯函數test::operator new 不可訪問test A;
上面是在堆上動態建立,下面是在棧上靜態建立
}

 

C++中兩種建立對象的方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.