簡體   English   中英

在C ++中,是否將const方法返回指向非const對象的指針視為不良做法?

[英]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類包含幾個方法,這些方法返回指向實用程序類的指針,例如InputManagerAudioManager等。

class Game
{
public:
    InputManager* inputManager() const { return m_inputManager; }
    ...

private:
    InputManager* m_inputManager;
    ...
}

因為inputManager()返回的對象不是常量,所以使inputManager()常量完全有意義嗎? (並且不應該這樣,因為InputManager需要可變才能更新其狀態,等等)

還是應該刪除方法的const修飾符以更准確地反映方法的行為? 這樣,如果我有一個const Game ,即使Gameconst ,我也無法調用inputManager()然后與Game的輸入管理器發生inputManager()

它取決於非const指針是指向const對象內部的某個對象,還是取決於它是否是新分配的可變的內存。

考慮一下返回字符串副本的東西; 即使原始字符串是const,返回的副本也可以是非const的很好。 副本的所有權從方法傳遞給調用代碼; 現在,確保副本被正確銷毀是調用代碼的問題(可能是非常小的問題)。

但是,從const對象內部返回指向對象的非const指針將是一個非常糟糕的主意。

完全可以接受。 const方法意味着您不會修改要調用其方法的對象-它不會對任何其他對象進行任何說明。 當然,該對象可以是“ this”的一部分,也可以是“ this”-但這超出了重點。

通常,“ const”比什么都更能保證前景,但是其基本思想是相同的-const方法表示“ this”是const,僅此而已。

我認為,無論是否為const,返回member的指針都是一個壞主意。

當對象返回其私有成員的句柄時,其他對象可以通過此句柄更改私有成員。 對象的狀態可能是不一致的,並且會引起很多麻煩。 即使存在const,調用方仍可以使用const cast來繞過此檢查。 因此,返回對象的任何私有成員的句柄不是一個好主意。

我認為const在這里並不重要。

通常會使用它來返回屬性的句柄(指針,引用):

  • 它將用戶與特定的實現聯系在一起,從而無法更改它
  • 它使得不可能強制執行不變式(非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;
};

您最好不要按值返回,這樣,如果您更改內部結構,則始終可以提供一種新方法,並在舊方法中進行一些轉換,以免破壞您的接口(將其標記為已棄用,並全部取消)。

請記住:人們因暴露自己的私人身份而被判入獄!

在您的情況下, GameInputManager對象似乎是單例。 在這種情況下,您只需確保僅存在一個Game實例(僅包含一個InputManager),並跳過const裝飾器。 如上所述,在這種情況下,我將返回對包含對象的引用,而不返回指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM