我遇到了一个有趣的理论,我想知道在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类是基的朋友,因此可以调用b.a()。然而,当它收到一个引用时,它可以接收到一个派生对象的引用,因此C将访问派生类中的私有区域,而不是派生对象的朋友。
这是简单的糟糕的代码设计,还是有一个安全的防范措施?当我为基重写operator<<并从内部调用一般的打印函数(操作符是基的朋友)时,发生了这样的情况。
发布于 2016-07-10 11:46:18
作为(基本和派生的)设计的框架,这是Herb 15年前倡导的一个典型的好设计--除了与类C交友是多余的,因为它可以调用公共函数run()。只有在只需要使用a()的情况下,C才需要成为朋友,以防run()有更多的功能需要避免(在这种情况下,我怀疑存在错误的设计)。我想知道我的阅读有什么问题,因为与前面的答案不同,我不认为a()是公开的,也没有看到base是一个私有库。尽情享受
发布于 2016-07-09 01:40:24
这里不需要任何保障措施。这就是C++的设计工作方式。
通过重写基类中的虚拟函数,派生类将重新实现它。但是,“重新实现”的定义包括继承基类中的所有行李。包括基类中的虚拟函数在本例中为public
这一事实。
派生类将重新实现的函数定义为private
这一事实并不改变它正在重写公共函数的事实。因此,它应该期望它仍然可以通过基类访问。
我想,最多可以说这是一种“怪癖”。底线是,如果要重写public
虚拟函数,重写过程不会改变它是公共函数的事实。在派生类中,使最重要的函数“私有”,是在马已经离开之后关闭谷仓。
您必须意识到,您正在重写一个公共虚拟函数。在某些情况下,我会说这甚至可以是一个功能。不难想象,特定的基类函数只应由直接引用基类的现有代码调用。任何具有指针或对派生类的引用的代码都是高级代码,不应该有任何调用基类函数的业务。当然,这是一种方法。这当然不是某种严格的安全性,而仅仅是编译器帮助您捕获逻辑或功能错误或某种设计错误的机制。
发布于 2016-07-09 02:17:00
嗯,不,这是不错的C++设计。这是糟糕的设计你的程序。
做类似的事情的程序
some_C.doSomething(some_derived);
将无法编译。这是因为您的Base
是Derived
的一个私有基础。因此,将Derived &
转换为Base &
无效。
上述情况的例外情况是,执行此操作的调用函数要么是成员,要么是friend
of Derived
。在这种情况下,行为由( Derived
的开发人员)控制,如果您做过这样的事情,这完全是您的责任。
https://stackoverflow.com/questions/38277223
复制相似问题