[英]In C++, is a const method returning a pointer to a non-const object considered bad practice?
在C ++中,是否將const方法返回指向非const對象的指針視為不良做法? 例如。 考慮以下方法:
// Makes perfect sense
bool isActive() const { return m_isActive; }
// Makes perfect sense, both consts ensure nothing is modified
const SomeObject* someObject() const { return m_someObject; }
// Makes perfect sense, no const because SomeObject is mutable,
// thus MyClass is indirectly mutable
SomeObject* someObject() { return m_someObject; }
// Makes no sense, if you're just returning a pointer to a const object,
// then the method should clearly be const since nothing can be modified
const SomeObject* someObject() { return m_someObject; }
最后一個組合使我感到困惑:以下做法是否被視為不良做法?
SomeObject* someObject() const { return m_someObject; }
因為該方法返回的類不是const,而是該方法,所以它毫無意義,因為您可以修改SomeObject
從而間接地修改您的類...那么,這種形式被認為是不好的做法嗎? 例如,您是否應該僅使用以下一項代替它?
const SomeObject* someObject() const { return m_someObject; }
SomeObject* someObject() { return m_someObject; }
實際情況:我正在編寫一個具有Game
類的智能手機游戲。 Game
類包含幾個方法,這些方法返回指向實用程序類的指針,例如InputManager
, AudioManager
等。
class Game
{
public:
InputManager* inputManager() const { return m_inputManager; }
...
private:
InputManager* m_inputManager;
...
}
因為inputManager()
返回的對象不是常量,所以使inputManager()
常量完全有意義嗎? (並且不應該這樣,因為InputManager
需要可變才能更新其狀態,等等)
還是應該刪除方法的const
修飾符以更准確地反映方法的行為? 這樣,如果我有一個const Game
,即使Game
是const
,我也無法調用inputManager()
然后與Game
的輸入管理器發生inputManager()
。
它取決於非const指針是指向const對象內部的某個對象,還是取決於它是否是新分配的可變的內存。
考慮一下返回字符串副本的東西; 即使原始字符串是const,返回的副本也可以是非const的很好。 副本的所有權從方法傳遞給調用代碼; 現在,確保副本被正確銷毀是調用代碼的問題(可能是非常小的問題)。
但是,從const對象內部返回指向對象的非const指針將是一個非常糟糕的主意。
完全可以接受。 const方法意味着您不會修改要調用其方法的對象-它不會對任何其他對象進行任何說明。 當然,該對象可以是“ this”的一部分,也可以是“ this”-但這超出了重點。
通常,“ const”比什么都更能保證前景,但是其基本思想是相同的-const方法表示“ this”是const,僅此而已。
我認為,無論是否為const,返回member的指針都是一個壞主意。
當對象返回其私有成員的句柄時,其他對象可以通過此句柄更改私有成員。 對象的狀態可能是不一致的,並且會引起很多麻煩。 即使存在const,調用方仍可以使用const cast來繞過此檢查。 因此,返回對象的任何私有成員的句柄不是一個好主意。
我認為const
在這里並不重要。
通常會使用它來返回屬性的句柄(指針,引用):
如果您開始使屬性直接可訪問,則它們與public
一樣好。
例子:
class Foo
{
public:
std::vector<Bar> const& bars() const; // Ooops, impossible to move to a `deque`
// or to enable polymorphic behavior
private:
std::vector<Bar> mBars;
};
您最好不要按值返回,這樣,如果您更改內部結構,則始終可以提供一種新方法,並在舊方法中進行一些轉換,以免破壞您的接口(將其標記為已棄用,並全部取消)。
請記住:人們因暴露自己的私人身份而被判入獄!
在您的情況下, Game
和InputManager
對象似乎是單例。 在這種情況下,您只需確保僅存在一個Game實例(僅包含一個InputManager),並跳過const裝飾器。 如上所述,在這種情況下,我將返回對包含對象的引用,而不返回指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.