友善和继承

时间:2013-08-12 11:34:31

标签: c++ inheritance

假设我有这段代码:

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

2 个答案:

答案 0 :(得分:1)

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

  

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

只要您有权访问B::~B,就可以致电A::~A。但您必须通过A进行调用,因为Z无法访问B

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

答案 1 :(得分:1)

这里至少涉及两个问题。

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

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

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