0

假设我有这个代码:

#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 的朋友?

4

2 回答 2

1

标准,§11.5/1“访问虚拟功能,”说

虚函数的访问规则(第 11 条)由其声明决定,不受稍后覆盖它的函数规则的影响。

因此B::~B,只要您有权访问A::~A. 但是你必须调用它,A因为Z没有访问权限B

顺便说一句,其中的朋友声明Z是无用的,因为其中没有任何内容是私有的或受保护的。

于 2013-08-12T11:56:58.927 回答
1

这里至少涉及两个问题。

是的,B 的析构函数将被调用。这就是多态性的工作方式,虚拟析构函数的工作方式,这是设计使然,这是一件好事。

一个在 B 中受保护(甚至是私有)但在 A 中是虚拟且可用(例如公共)的成员函数可以通过 A* 调​​用这一事实乍一看可能有点奇怪,但它也是设计使然。有什么选择?我能看到的唯一其他选择是禁止增加虚拟成员函数限制的继承;这有什么好的目的?

如果您不希望某个方法可访问,请不要从可访问的虚拟父方法派生它。

于 2013-08-12T12:01:25.457 回答