假设我有这段代码:
#include <iostream>
using namespace std;
class A
{
protected:
virtual ~A() { cout << "A destructor reached." << endl;}
friend class Z;
};
class B : public A
{
protected:
virtual ~B() { cout << "B destructor reached." << endl; }
};
class Z
{
public:
void Test();
friend class A;
};
void Z::Test()
{
A* derived = (A*) new B();
delete derived;
}
int main()
{
Z test;
test.Test();
}
将会发生什么事情,B析构函数会被调用吗?这合法吗?如果不是,有没有办法调用派生构造函数而不使每个类派生自Z的朋友?
答案 0 :(得分:1)
标准,§11.5/ 1“访问虚拟功能,” p>说
虚函数的访问规则(第11条)由其声明确定,不受稍后覆盖它的函数规则的影响。
只要您有权访问B::~B
,就可以致电A::~A
。但您必须通过A
进行调用,因为Z
无法访问B
。
顺便说一句,Z
中的朋友声明是无用的,因为没有任何内容是隐私的或受其保护。
答案 1 :(得分:1)
这里至少涉及两个问题。
是的,B的析构函数将被调用。这就是多态性的工作方式,这就是虚拟析构函数的工作方式,它是设计的,这是一件好事。
A中可以通过A *调用B中受保护(甚至是私有)但虚拟和可用(例如公共)的成员函数可能看起来有点奇怪,但它也是设计的。有什么选择?我能看到的唯一另一个选择是禁止继承增加虚拟成员函数的限制;这有什么好处?
如果您不希望方法可访问,请不要从可访问的虚拟父方法派生它。