2011-10-06 63 views
2
class A 
{ 
    ... 

    public: 
     shared_ptr<Logger> GimmeLogger() const 
     { 
      return m_logger; 
     } 

    private: 
     shared_ptr<Logger> m_logger; 
}; 

class A,應該GimmeLoggerconst或非const應該在語義上還是語法上使用「const」?

因爲它是一個簡單的getter,它不會修改*this(句法const),所以它應該是const

但是另一方面,它返回一個非const指針到它擁有的另一個對象(語義非const)。

+0

而不是'm_logger'是'shared_ptr '? –

+1

Scott Mayers書(Effective C++)第21項對'const'進行了一次有趣的討論。如果你正在編程C++,這本書很值得一讀。基本上,儘可能使用'const'並使用擺動室。 –

+0

您是否特別詢問伐木者或一般的「擁有」物品?如果不從函數式編程的角度深入研究monad的概念,那麼考慮一個記錄器可能是數據拋出而不真正改變其狀態的東西,這可能是合理的。因此,沒有理由不應該使用屬於const對象的記錄器。 –

回答

4

如果你作出這樣的非const,那麼你就不能這樣寫:如果你想寫這個

void f(const A & a) 
{ 
    auto v = a.GimmeLogger(); //error 
} 

左右;也就是說,如果你想在const對象上調用GimmeLogger,那麼就要使GimmeLogger成爲一個const成員函數,因爲你不能在const對象上調用一個非const成員函數。但是,您可以在非const對象(以及const對象)上調用const成員函數。

在一個const成員函數中,每個成員都是語義上的const對象。所以函數中m_logger的類型變爲const share_ptr<const m_logger>。所以相應地改變返回類型。

+0

雙重否定總是讓我覺得...... –

+0

*呃......「第一部分的派對應該在本合約中被視爲第一部分的派對。」* - 來自「歌劇之夜」 –

1

是的,它應該是constconst函數的性質與返回類型的const無關。

我明白了你的觀點,但我認爲這種功能仍然是const

1

因爲const是一個關鍵字,檢查語法,但它應該被用來語義,那就是,在你的設計操作不改變你的類的可視狀態應標記爲const

這是mutable關鍵詞背後的整體思路:將標記的成員作爲使語法檢查語義匹配這個不走對象的可見狀態的一部分的能力。在你的具體情況下,因爲你是拷貝一個指針,你甚至不需要在那裏使用mutable(這實際上是const-correctness的弱點之一,因爲返回一個非const指針不會觸發錯誤while編譯,即使你打開了對你的對象的變化的大門)

在這種特殊情況下,另一方面,我沒有看到一個很好的理由,該對象將公佈它的記錄器...這是拋開常量的正確性,爲什麼你需要授予訪問記錄器的權限?

1

一般來說,當你可以避免它時,你不應該返回一個成員數據的句柄。儘量審查您的設計並找到解決方法。這就是說,如果你必須,它應該是const。這使您可以調用const對象以及非常量對象的功能。例如參見std::string::c_str()。你也可以重載函數,這樣你就可以得到兩個,就像標準容器用迭代器一樣。

如果有疑問,請查看標準庫中的提示。

相關問題