2009-04-16 194 views
72

我有一個關於const指針的基本問題。我不允許使用const指針調用任何非const成員函數。然而,允許我做一個常量指針:刪除一個指向const(T const *)的指針

delete p; 

這將調用類在本質上是一個非const「方法」的析構函數。爲什麼這是允許的?是否只是爲了支持這一點:

delete this; 

或者是否還有其他一些原因?

回答

90

它支持:

// dynamically create object that cannot be changed 
const Foo * f = new Foo; 

// use const member functions here 

// delete it 
delete f; 

但要注意的問題不限於動態創建的對象:

{ 
const Foo f; 
// use it 
} // destructor called here 

如果析構函數不能在const對象調用,我們不能使用const對象在所有。

+17

+1最新編輯。我認爲這是真實的原因。自動析構函數調用const對象 - 幾乎與delete f相同;其中f - 常量上的指針。 – bayda 2009-04-16 08:43:34

37

就這麼說吧 - 如果它不是不是允許的話,就沒有辦法在不使用const_cast的情況下刪除const對象。

從語義上講,const表示對象應該是不可變的。但這並不意味着該對象不應該被刪除。

+0

析構函數可以用相當猛烈的方式改變對象,所以這一定是我以前沒有意識到的「不可變」這個詞的一些奇怪用法。 – DarthGizka 2016-05-15 08:34:47

5

不應將構造函數和析構函數視爲「方法」。它們是初始化和拆除一個類的對象的特殊構造。

「常量指針」用於指示當對象處於活動狀態時對其執行操作時,對象的狀態不會被更改。

4

另一種方式來看待它:一個const指針的確切含義是,你將無法進行更改指向的對象,將通過這或者是可見的任何其他指針或引用同一個對象。但是,當一個對象自毀,所有其他的指針之前由現在刪除的對象佔用的地址不再指向該對象。它們存儲相同的地址,但該地址不再是任何對象的地址(事實上,它很快會被重新用作不同對象的地址)。

如果C++中的指針表現得像弱引用,即一旦對象被銷燬,所有現存的指針立即被設置爲0,這種區別就會更加明顯。 (這是在運行時被認爲是太昂貴的東西,施加在所有C++程序上,事實上它不可能使它完全可靠。)

6

我不允許調用任何非const成員函數使用const指針。

是的,你是。

class Foo 
{ 
public: 
    void aNonConstMemberFunction(); 
}; 

Foo* const aConstPointer = new Foo; 
aConstPointer->aNonConstMemberFunction(); // legal 

const Foo* aPointerToConst = new Foo; 
aPointerToConst->aNonConstMemberFunction(); // illegal 

您已經將const指針與非const對象的非const指針混淆到非const對象。

話雖如此,

delete aConstPointer; // legal 
delete aPointerToConst; // legal 

是合法的刪除或者,對於已經被這裏的其他答案陳述的理由。