2013-10-06 43 views
1
class A 
{ 
public: 
    A(){ val = 0; p = new int; *p = 0; } 
    //void fun_1()const{ val = 1; } not allowed 
    void fun_2()const{ *p = 1; } 
    void display()const{ cout<< val <<' '<< *p <<endl; } 
private: 
    int val; 
    int * p; 
}; 

int main() 
{ 
    const A a; 
    a.fun_2(); 
} 

更改const成員函數如fun_1()const中的成員數據是不允許的。但是,當數據不是直接成爲對象的成員,而是分配了存儲並分配給對象時,const函數無法保護它。 fun_2()const可以更改p指向的數據,例如它是一個常量函數。在C++中,如果成員指針指向某些數據,如何保護該數據不被修改?

有什麼辦法保護p指向的數據?

+0

你可以讓它變成一個'const int的*'(或更好的,一個'常量的std ::的unique_ptr ') 。 – chris

+0

@chris一個'std :: unique_ptr '?或者真的是一個'const std :: unique_ptr '? (注意'operator *'等是const成員函數) – dyp

+1

您的問題是否可以在const函數中修改* p? IE瀏覽器。你不介意存在,或者你實際上還想成爲,可以在非const方法中改變* p? – Kindread

回答

3

使編譯器保護指向對象相對簡單,但這不是自動完成的,因爲它並不總是正確的做法。

template<typename T> 
class constinator_ptr 
{ 
    T* p; 
public: 
    explicit constinator_ptr(T* p_init) : p (p_init) {} 

    T*& ptr() { return p; } // use this to reassign, or also define operator=(T*) 

    T* operator->() { return p; } 
    const T* operator->() const { return p; } 
    T& operator*() { return *p; } 
    const T& operator*() const { return *p; } 
}; 

到位您的原始指針就用這個,像這樣:

class A 
{ 
public: 
    A() : val{0}, p{new int(0)} {} 
    //void fun_1()const{ val = 1; } not allowed 
    void fun_2()const{ *p = 1; } // now causes error 
    void display()const{ cout<< val <<' '<< *p <<endl; } 
private: 
    int val; 
    constinator_ptr<int> p; 
}; 
2

只需編寫您的成員函數,以便它們不允許調用方修改對象。只要指針是私有的,它指向的任何東西只能被其他成員函數看到。如果你不公開一個改變指向對象的成員函數,那麼你的類的用戶就不能改變它。

請注意,您可以將該成員聲明爲「指向常量」(與常量指針不同)。

int const* p是一個指向const int的指針(指針可以改變,但是它指向的int不能),而int* const是一個指向int的常量指針(指針不能改變 - 它總是指向相同的int,但該int的值可以更改)。當然,int const* const是一個const int指針。指針和int都不能被修改。

然而,這並不會真正幫助你執行的是「const成員函數不應該修改指向的對象,但非const成員函數」(因爲一個指向const int的將總是點到const int的,即使從非const成員函數使用)

+0

'val'和數據'p'指向的都是成員變量,它們是相同的。編譯器負責保護'val',爲什麼它不保護指向的對象? – doyoubi

+1

@ user2838259:因爲你沒有要求。 –

+0

@ user2838259:因爲它們是規則:可以有一個指向非const對象的const對象。這就是'const'的工作方式:) – jalf

2

只是聲明指針至恆:

const int * p; 


void fun_2()const{ *p = 1; } // main.cpp:36: error: assignment of read-only 
           // location ‘*(const int*)((const B*)this)->B::p’ 

在這種情況下,整數由p指向不能在所有被改變,不管它是不是ifrom a constnon-const函數體。如果你仍然希望能夠從non-const成員函數中更改int的值,則不得在類外部暴露指針,使指針保持私有狀態並相應地使用它。

+2

現在非''const'成員函數也不能改變它。 –

2

一個簡單而通用的解決方案是您自己的具有深常量語義的智能指針類。只需在deepconst<T>中包裝一個普通指針,將const T* operator->() constconst T& operator*() const添加到通常的非常量版本中,然後完成。