侵犯隐私 - C ++标准如何处理它?

时间:2013-04-19 15:12:59

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

考虑以下代码段。

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

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

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

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

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

Q1。 C ++标准对这种运行时异常有什么发言权吗?

Q2。我想从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;
}

3 个答案:

答案 0 :(得分:7)

  

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

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

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

  

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

该标准根本没有任何关于警告的说法;它只是定义了格式良好的代码的行为。编译器编写者可以决定哪些警告可能有用;并警告所有私人覆盖,以防万一你并不意味着它们会覆盖它听起来会产生很多误报。

答案 1 :(得分:2)

访问规范不能放松,只能收紧。
基类中Sayhi()public所以基本上所有派生和覆盖它的类都应该期望方法为public,没有入侵。由于方法被声明为public,因此已明确指定了覆盖函数的访问规范。

答案 2 :(得分:0)

即使你的问题现在已经回答了,我想补充说明。

虽然您认为这是一个“异常”并且想要进行诊断,但这实际上很有用:您可以确保您的实现只能以多态方式使用。派生类应该只有一个公共ctor,没有其他公共职能,所有重新实施的成员职能应该是私人的。