继承与朋友:安全机制?

时间:2016-07-09 00:57:35

标签: c++ c++11 inheritance friend

我遇到了一个有趣的理论,我想知道c ++中是否存在针对此问题的安全机制。

class Base
{
 private:
 virtual void a(){};
 friend class C;
}

class Derived: public Base
{
void a() override {};
}

class C{

public doSomething(const Base& b) {b.a();};

}

所有这些都是合法的 - C类是base的朋友,因此可以调用b.a()。但是,当它收到引用时,它可以接收对Derived对象的引用,因此C将访问Derived类中的私有区域,而不是派生的朋友。

这只是糟糕的代码设计还是对此有安全防范?覆盖运算符<<<<<<<<对于基础,并从内部调用一般打印功能(操作员是基地的朋友)。

3 个答案:

答案 0 :(得分:4)

此处不需要保护措施。这就是C ++的设计工作方式。

通过覆盖基类中的虚函数,派生类重新实现它。但是"重新实现"的定义包括继承基类的所有行李。包括在这种情况下基类中的虚函数为public这一事实。

派生类将重新实现的函数定义为private的事实并没有改变它覆盖公共函数的事实。并且,因此,它应该期望它仍然可以通过基类访问。

我想,至多,你可以把它叫做'#34; quirk"。最重要的是,如果您要覆盖public虚拟函数,则覆盖的过程不会改变它是公共函数的事实。在派生类中制定覆盖函数" private",在马匹离开后关闭谷仓。

您必须意识到您正在覆盖公共虚拟功能。在某些情况下,我说这甚至可以成为一种功能。想象一下特定基类函数只能由直接引用基类的现有代码调用的情况并不难。任何具有指针或对派生类的引用的代码都是更高级别的代码,不应该有任何业务调用基类的函数。当然,这是一种方法。这当然不是某种形式的严密安全性,而仅仅是编译器帮助您捕获逻辑或功能错误或设计某种错误的机制。

答案 1 :(得分:4)

嗯,不,这不是C ++的糟糕设计。这是你的程序的糟糕设计。

执行类似

的程序
 some_C.doSomething(some_derived);

将无法编译。这是因为您的BaseDerived的私人基础。因此,将Derived &转换为Base &无效。

上述例外情况是,执行此操作的调用函数是friend的成员还是Derived。在这种情况下,行为由Derived的(开发者)控制,如果你做了这样的事情,那完全是你的责任。

答案 2 :(得分:1)

作为设计的骨架(Base和Derived),这是一个典型的优秀设计,由Herb Sutter 15 years ago倡导 - 除了让C级朋友多余,因为它可以呼叫公众function run()。只有当需要使用a()时,C才需要成为朋友,以防run()有更多功能要避免(我怀疑在这种情况下设计不好)。 我想知道我的阅读有什么问题,因为,与之前的答案不同,我没有看到a()是公开的,也没有看到Base是私人基础。 享受