2013-04-02 87 views
0
class Foo{}; 

class BarParent 
{ 
    Foo* p_foo; 

    public: 
    BarParent(Foo * const p_x) //OR BarParent(Foo const * x) OR BarParent(Foo * x) 
          //OR (Foo const * const x) 
    { 
     p_foo = x; 
    } 
}; 


class BarChild: public BarParent 
{ 
    public: 
    BarChild(const Foo& x) 
    : BarParent(& x){} 
}; 

我打算是:使用BarChild構造函數時,點xp_foo。有沒有辦法做到這一點。`const`ness,引用和函數調用

我已經試過BarParent ctor沒有運氣的所有可能的簽名。

總結:出於某種原因,我被混淆的是分配(指針到非const對象)至(指針const對象)的事實打破const限制。

+0

你應該把'p_foo'一個'富常量*'。 –

+0

你想用'p_foo'或'x'做什麼?如果你想修改它,你需要傳入一個非const指針。如果不是,你需要在我的應用程序中創建'p_foo'' const' – maditya

+0

@AndyProwl它不是,並且可以通過其他函數更改 – aiao

回答

3

我提出了兩種備選方案:

  1. 要麼你確實想在BarChild構造採取const Foo&,在這種情況下,你需要堅持你的承諾,你將永遠不會允許Foo對象是改性。爲此,p_xp_foo都需要爲const Foo*(即,指向const Foo的指針)。如果它是指向非constFoo的指針,那麼您將有效地允許修改對象,違反您的承諾。

    class BarParent 
    { 
        const Foo* p_foo; 
    
        public: 
        BarParent(const Foo* p_x) 
        { 
         p_foo = x; 
        } 
    }; 
    
  2. 或者,你真的想保持Foo*而非const Foo*,所以BarChild構造應採取Foo&而不是const Foo&的。這樣,你就不會說保留對象const

    class BarChild: public BarParent 
    { 
        public: 
        BarChild(Foo& x) 
        : BarParent(& x){} 
    }; 
    
+0

您能否提供一個關於const的好資源?請解釋如何編寫1-指針指向'const',2-'const'指針指向可變指針,3'const指針指向const對象 – aiao

+0

@aiao規則:'const'適用於任何它的左邊,除非沒有什麼,在這種情況下它適用於右邊。所以'int * const'是「const指向int的指針」,並且'int const *'和'const int *'都是「指向const int的指針」。 –

1

可以拋棄的常量性與const_cast

p_foo = const_cast<Foo *>x; 

但是這通常是一個壞主意,原因有二:

  • 常量,正確性的整點是要記錄/執行關於誰可以修改什麼的某些期望。 const_cast顛覆了這一點。

  • 在一些情況下,可能甚至釋放未定義行爲(即,通過非const指針修改底層對象真正是const)。

一般情況下,找到一種方法,以避免需要做這個擺在首位(我不能做任何具體建議,因爲我不知道你的用例是什麼)。

+0

任何更好的替代品? – aiao

+0

@aiao:查看我更新的答案。 –

2

你是一個誤解是const Foo&什麼。

A const Foo&是變量的別名或引用,通過它您不能使其被修改(不使用const_cast或C風格的變體)。這不僅僅是一種承諾,即使不是「現在」修改它,但它也是一個承諾,你告訴這個變量的每個人都不會修改它。

如果你想存儲一個指向這個數據的指針來修改它,你不應該把它作爲const Foo&,而應該是Foo&

所以解決您的代碼,重寫BarChild如下:

class Foo{}; 

class BarParent 
{ 
    Foo* p_foo; 

    public: 
    BarParent(Foo * p_x): 
     p_foo(p_x) 
    {} 
}; 

class BarChild: public BarParent 
{ 
    public: 
    BarChild(Foo& x): 
    BarParent(& x) 
    {} 
};