2014-08-29 61 views
5

我想知道如何通過const方法保護對象的非常量指針成員。例如:對非常量指針成員的C++ const方法

class B{ 
    public: 
     B(){ 
      this->val=0; 
     } 

     void setVal(){ 
      this->val = 2; 
     } 

    private: 
     int val; 
}; 

class A{ 
    public: 
     A():b(new B){} 
     void changeMemberFromConstMethod() const{ 
      this->b->setVal(); 
     } 
    private: 
     B * b; // how to protect data pointed in A::changeMemberFromConstMethod 
} 

是否可以「保護」指向他的方法的A :: b數據? 經過對網絡的大量研究,尚未得到滿意的反饋。

感謝您的幫助。

+6

'''醫生,當我這樣做的時候會很痛苦 - 「所以不要這樣做。」這不像任何人扭動你的手臂,並迫使你從const方法調用setVal。我想我不明白問題的本質。 – 2014-08-29 20:45:31

+0

這僅僅是爲了舉例的目的。例如,它就像我要設置的保證,即不修改指定的B數據。 – Alex 2014-08-29 20:50:16

+0

如果你不想修改'* b',那麼就不要。我仍然沒有把握困難的性質。 – 2014-08-29 20:52:11

回答

10

事情是這樣的,也許:

template <typename T> 
class deep_const_ptr { 
    T* p_; 
public: 
    deep_const_ptr(T* p) : p_(p); 

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

class A { 
    deep_const_ptr<B> b = new B; 
}; 

deep_const_ptr行爲就像在A的常量方法const T* const指針,在非const方法T*等。進一步豐富課程是爲讀者留下一個練習。

+1

+1不錯的解決方案。 – 2014-08-29 21:30:04

+0

這很有趣!但是如何選擇合適的運營商? – Alex 2014-08-29 21:32:27

+2

當然,通過過載resoultion。能怎樣? – 2014-08-29 21:35:49

6

如果您的A成員從

B* b; 

改變

B b; 

那麼你會得到預期的行爲。

class A{ 
    public: 
     A() : b() {} 

     void changeMemberFromConstMethod() const{ 
      this->b.setVal(); // This will produce a compiler error. 
     } 
    private: 
     B b; 
} 
+1

我知道這一點。謝謝 – Alex 2014-08-29 20:58:37

4

你的問題是,一個const方法,使所有的成員變量const。但是,在這種情況下,它會使指針const。具體來說,就好像您擁有的是B * const b,這意味着指向(仍然)可變的B的常量指針。如果您沒有聲明您的成員變量爲const B * b(即指向常數B的可變指針),則無法保護此行爲。

如果你需要的是一個const B,然後通過各種手段,定義A這樣的:

class A { 
public: 
    A() : b(new B) {} 

    // This WILL give an error now. 
    void changeMemberFromConstMethod() const { b->setVal(); } 
private: 
    const B* b; 
} 

但是,如果A發生變異B其他方法,那麼所有你能做的就是確保B做在Aconst方法中不會突變。

+0

我同意你的意見。但如果我設置: void changeMemberFromConstMethod(){b-> setVal();} 這將失敗另一方面。我想這個const方法說:const B * b const;你看 ? – Alex 2014-08-29 21:11:00

1

在這種情況下,嘗試使用以下通用方法來保護通過指針引用的對象的常量。

  1. 重命名乙* B

    B *my_pointer_to_b; 
    

    並相應地改變在構造函數初始化。

  2. 實現兩個存根:

    B *my_b() { return b; } 
    const B *my_b() const { return b; } 
    
  3. 替換所有現有的引用與my_b(到B),在現有的代碼。展望未來,在任何新代碼中,總是使用my_b()將指針返回給b。

可變方法將得到一個非常量指針B; const方法將得到一個指向B的const指針,並且額外的重命名步驟確保所有現有的代碼都被迫遵守新的制度。

+0

這是一個有趣的方法。但它有點扭曲^^。如何根據const或not方法找到正確的方法? – Alex 2014-08-29 21:30:52

+1

const方法只能調用其他const方法。在const方法中,「this」是一個常量指針,而不是一個可變指針。這實際上是一個相當常見的設計模式。 – 2014-08-29 22:00:04

+0

謝謝你的光 – Alex 2014-08-29 22:03:28

相關問題