【问题标题】:Intruding privacy - How does the C++ standard handle it?侵犯隐私 - C++ 标准如何处理它?
【发布时间】:2013-04-13 00:54:59
【问题描述】:

考虑下面的代码 sn-p。

方法 Sayhi() 在 Base 类中具有公共访问权限。

Sayhi() 已被 Derived 类重写为私有方法。

通过这种方式,我们可以侵入某人的隐私,而 C++ 无法检测到它,因为事情发生在运行时。

我知道这是“纯粹的”编译时检查。但是当使用一些厚继承层次时,程序员可能会错误地更改访问说明符。标准不应该至少有发言权吗?某种警告信息。

为什么当覆盖或虚函数的访问说明符不同时,编译器至少不会发出警告消息?

第一季度。 C++ 标准对这种运行时异常有什么看法吗?

第二季度。我想从 C++ 标准的角度理解,为什么标准不强制编译器实现者进行警告诊断?

#include <iostream>

class Base {
    public:
        virtual void Sayhi() { std::cout<<"hi from Base"<<std::endl; }
};

class Derived : public Base
{
    private:
        virtual void Sayhi() { std::cout<<"hi from Derived"<<std::endl; }
};


int main() {
    Base *pb = new Derived;
    // private method Derived::Sayhi() invoked.
    // May affect the object state!
    pb->Sayhi(); 
    return 0;
}

【问题讨论】:

标签: c++ c++11 polymorphism standards access-specifier


【解决方案1】:

即使您的问题已经得到解答,我还是想补充一点。

虽然您认为这是“异常”并希望进行诊断,但 这实际上很有用:您可以确保您的实现只能用于多态。派生类应该只具有public ctor 而没有其他公共函数,所有重新实现的成员函数都应该是私有的。

【讨论】:

    【解决方案2】:

    C++ 标准是否对此类运行时异常有任何发言权?

    没有。访问控制纯粹是编译时的,影响可以使用哪些名称,而不影响可以调用哪些函数。

    所以在您的示例中,您可以访问名称Base::Sayhi,但不能访问Derived::Sayhi;并且访问Base::Sayhi 允许您虚拟调用任何覆盖它的函数。

    为什么标准不强制编译器实现者进行警告诊断?

    标准对警告完全没有任何规定;它只是定义了格式良好的代码的行为。由编译器编写者决定哪些警告可能有用;并警告所有私有覆盖,以防万一你不是要覆盖它们听起来会产生很多误报。

    【讨论】:

    • 是的,我知道这是“纯粹的”编译时检查。但是当使用一些厚继承层次时,程序员可能会错误地更改访问说明符。标准不应该至少有发言权吗?某种警告信息。
    • @Arun:问题在于“程序员可能错误地更改访问说明符。”。使用 C 和 C++,您可以朝自己的脑袋开枪,但这并不意味着应该这样做。编写糟糕的代码没有任何借口。期望编译器检测到错误代码是完全错误的。这是程序员而不是编译器的责任。
    • @Alok,是的,我理解您想要传达的所有内容,但是在修复某人的代码时遇到了一些糟糕的事情!只需一条警告消息,事情就可以轻松解决,程序员在遇到糟糕的情况时不会忽略它:)
    • @Arun:标准对警告没有任何规定;它只是定义了格式良好的代码的行为。由编译器编写者决定哪些警告可能有用;并警告所有私有覆盖,以防万一您不是要覆盖它们听起来会产生很多误报。
    • @Mike,有道理,感谢您从 C++ 标准的角度进行澄清。
    【解决方案3】:

    访问规范不能放松,只能收紧。
    Sayhi()是基类中的public,所以基本上所有从它派生和覆盖的类都应该期望方法是public,没有入侵。覆盖函数的访问规范已经很好地指定了,因为该方法一开始就声明为public

    【讨论】:

    • 入侵来自Derived类的POV,它认为它正在定义一个private函数。然后是Base,突然之间(可能直到 v1.1)SayHi 是一个覆盖。所以,(1)这是一个脆弱基类的实例,它真正的意思是派生类必须注意它们的基类; (2) 如果您认为隐私是应该保留的东西,那么向基类添加虚函数是一种源向后不兼容的更改。还有一个二进制不兼容的变化,ofc,但这很明显,而源不兼容可能不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    • 2019-06-30
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    相关资源
    最近更新 更多