2011-06-20 60 views
2

我有幾個類其中一個保持引用的其他對象:常量性參考類成員

class Inner {}; 

class Outer { 
    Inner & in; 

public: 
    Outer(Inner & in) : in(in) {} 
}; 

如果我要創建常量引用內,外圈的對象?我是否必須爲此編寫特定的課程,說OuterConst?

UPD:使用模板的任何整潔的解決方案?爲了避免在OuterConst類中重複代碼。

UPD2:當內部沒有const時它應該是可以修改的(所以我不能只在當前的外部實現中向內部成員添加const)。

回答

1

您可以存儲一個const引用,並在需要時使用const_cast來轉換const。如果添加一些運行時檢查,它也是安全的。

class Inner { /* ... */ }; 

class Outer { 
    Inner const & in; 
    bool const inIsConst; 

    Inner & inMutable() 
    { 
     if (inIsConst) 
      throw std::logic_error("in is const."); 
     else 
      return const_cast<Inner &>(in); 
    } 

public: 
    Outer(Inner const & in) : in(in), inIsConst(true) {} 
    Outer(Inner & in) : in(in), inIsConst(false) {} 

    // always safe 
    void Foo() { std::cout << in.getFoo(); } 

    // will throw if *this was constructed with a const Inner 
    void Bar() { inMutable().setFoo(in.getFoo() + 1); } 
}; 

當然,你總是可以分成兩類這樣的:一個是不能改變in,另一個可以。

要做到這一點,你既可以推導出從類不能改變in類。或者你可以從一個具有共同功能的共同基類派生出保護成員,並在派生類中使用using Base::Function公開適當的基類。

6

如果我必須從const引用創建Outer對象到Inner,該怎麼辦?

那麼,你不能。這是非常多的。如果Outer只需要調用Inner的const成員函數,那麼將其作爲一個const引用 - 否則,你的類依賴於一個可變的Inner對象,你不應該從const引用創建一個Outer對象。

1

這取決於。如果Outer這兩個角色對於不同的常量而言是不同的(一個是必須編輯的,另一個不是),那麼是的。

但是,如果兩個角色是相同的(這意味着不會對const或非const引用進行任何更改),那麼總是以const Inner&作爲參數。如果傳遞非const參數,它將自動「升級」到const之一。

3

問題是Outer是否需要修改Innerin。如果是這樣,你應該保留in作爲Inner &。在這種情況下,如果您有const Inner &,那麼當然不能將它傳遞給Outer,因爲參考不允許您修改參考的Inner,但Outer確實需要修改Inner

如果Outer並不需要修改Inner,那麼你應該只寫in作爲const Inner &,在這種情況下Outer可與一個Inner &const Inner &進行初始化。

你當然可以寫:

class Inner {}; 

template <class T> 
class Outer { 
    T& in; 

public: 
    Outer(T& in) : in(in) {} 
}; 

然後初始化Outer<Inner>型或Outer<const Inner>的對象。但Outer必須在這兩種情況下做一些不同的事情,否則,您可以只製作in a const Inner &。在這種情況下,你可能會更好地編寫單獨的類,以便明確表示Outer做了不同的事情。