3

考虑下面的代码片段。

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;
}
4

3 回答 3

7

C++ 标准对这种运行时异常有什么看法吗?

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

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

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

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

于 2013-04-19T15:18:54.833 回答
2

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

于 2013-04-19T15:16:51.990 回答
0

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

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

于 2013-04-19T15:51:31.893 回答