传递复杂类型时的const-correctness

时间:2013-04-16 07:30:25

标签: c++

所以,我有四个班级:

App - 这代表了应用程序的入口点

MainPage - 这代表主屏幕

Authenticator - 这表示用于身份验证的帮助程序/实用程序类

LoginPage - 这表示登录屏幕。

App,MainPage和LoginPage都有指向Authenticator的指针,实际上,当用户启动应用程序,到达主屏幕并提示记录时,它实际上从App传递到MainPage,再传递给LoginPage在.App创建MainPage,如果MainPage需要登录,它会创建LoginPage。 Authenticator指针在创建时传递。

让我们说Authenticator看起来像这样:

class Authenticator {
public:
   std::string GetToken() const;
   void Login(std::string username, std::string pass);
}

现在,App将创建一个指向Authenticator的普通非常量指针,但由于我不希望MainPage能够修改Authenticator,我希望它存储一个const指针(即它只能调用const)成员函数)。但是,我希望LoginPage能够调用非const成员函数,比如Login(),所以当我将我的Authenticator从MainPage传递给LoginPage时,我需要抛弃const-ness。

我的问题是:在这种情况下这样做是不是很糟糕?一个不允许修改对象的类是否应该能够将它传递给一个可以的类?或者让App同时创建MainPage和LoginPage更好,并给它们两个相同的Authenticator开始?我唯一的问题是我主动创建一个LoginPage,而不是懒惰,我更喜欢懒惰地做。

提前致谢。

4 个答案:

答案 0 :(得分:2)

从Apps的角度来看,MainPage 正在修改身份验证器。如果它直接这样做或者呼叫另一方(LoginPage)代表它这样做并不重要。所以MainPage应该得到一个非const指针,然后应该将它传递给它的子页面进行登录。

如果你想确保你的MainPage不修改Authenticator,你可以为它存储这个指针的基类,并有一个方法来调用登录对话框。 Authenticator是私有的,方法受到保护。然后,您可以派生自己的MainPageDerived,它没有(合法的,非hacky)修改Authenticator的机会,但如果需要可以调用LoginPage。

请注意,我说可以,因为对于3个班级,我认为这样做过度工作。但是,如果将来有更多页面,这可能是一种有效的方法。

答案 1 :(得分:1)

你错过了逻辑常量概念的重要部分。当一个类接受const对象的指针(或引用)时,它承诺永远不要以可以修改对象的方式使用指针/引用。这当然意味着传递给可以修改它的其他人。

换句话说,如果MainPage计划要求某人为其修改Authenticator(也就是说,将非const指针传递给其他人),那么它也负责修改,因此应该存储一个非const指针。

答案 2 :(得分:1)

从界面的角度来看:如果你有MainPage( Authenticator const* ),那么你就不知道MainPage 会修改Authenticator的可观察状态。 直接或间接 - 如果MainPage后来通过它 指向另一个将修改对象的类的指针 违反了合同。因此,在您的情况下,它是const正确性 需要MainPage( Authenticator* ):代码构建 MainPage并不关心修改是直接的还是 间接;它只是想知道合同是什么,那 它得到了支持。

答案 3 :(得分:0)

仅为MainPage提供所需内容。您可以通过以下几种方式来看待这一点。它可能需要:

  • AuthenticationTokenSource,提供最新的Token
  • AuthenticatedExectuor执行Action MainPage定义的AuthenticatedExectuorAction提供身份验证{{1}}

可能有其他方法,但这些是第一个想到的。