虚拟析构函数测试失败

时间:2015-04-05 06:02:02

标签: c++

#include <iostream>
#include <string>

using namespace std;

class Base {
    virtual ~Base() = default;
};

class Derived1 : protected Base {};
class Derived2 : protected Derived1{};
class Derived3 : protected Derived2{};

int main() {
    Base* b[] = {new Base, new Derived1, new Derived2, new Derived3};
    delete[] b;
    cin.get();
    return 0;
}

这给了我以下编译错误,我只关注我的教学内容:

  

警告1警告C4624:&#39; Derived1&#39; :无法生成析构函数,因为基类析构函数不可访问或删除

     

警告2警告C4624:&#39; Derived2&#39; :无法生成析构函数,因为基类析构函数不可访问或删除

     

警告3警告C4624:&#39; Derived3&#39; :无法生成析构函数,因为基类析构函数不可访问或删除

     

错误4错误C2243:&#39;输入&#39; :转换自&#39; Derived1 *&#39;到&#39; Base *&#39;存在,但无法访问

     

错误5错误C2243:&#39;输入&#39; :来自&Derve2 *&#39; Derived2 *&#39;到&#39; Base *&#39;存在,但无法访问

     

错误6错误C2243:&#39;输入&#39; :来自&#39; Derived3 *&#39;到&#39; Base *&#39;存在,但无法访问

     

警告7警告C4154:删除数组表达式;转换为提供的指针

     

8智能感知:转换为无法访问的基类&#34; Base&#34;不允许

     

9智能感知:转换为无法访问的基类&#34; Derived1&#34;不允许

     

10智能感知:转换为无法访问的基类&#34; Derived2&#34;不允许

2 个答案:

答案 0 :(得分:5)

第1期

将析构函数放在public的{​​{1}}部分。

Base

相当于:

class Base {
    virtual ~Base() = default;
};

将其更改为:

class Base {
  private:
    virtual ~Base() = default;
};

第2期

class Base {
  public:
    virtual ~Base() = default;
};

使用Base* b[] = {new Base, new Derived1, new Derived2, new Derived3}; 运算符三次构造对象。你需要调用new三次 - 每个指针一次。

而不是

delete

使用

delete[] b;

第3期

能够使用

delete b[0];
delete b[1];
delete b[2];

您必须Base* p = new Derived1; Base基类为public,而不是Derived1

更改

protected

class Derived1 : protected Base {};
class Derived2 : protected Derived1{};
class Derived3 : protected Derived2{};

答案 1 :(得分:3)

你有三大问题:

首先,您滥用delete[]。当您使用new []分配数组时,它将被调用。你还没有那样做。您需要遍历数组b,在每个元素上调用delete

其次,您的Base虚拟析构函数为private。它必须可以被派生类型访问,因此请将其public

第三,所以DerivedN 是-a Base,您需要进行继承public。如果没有这个,你就不能将指向Derived对象的指针分配或初始化为指向Base的指针。

这是一个固定版本:

class Base {
 public:
    virtual ~Base() = default;
};

class Derived1 : public Base {};
class Derived2 : public Derived1{};
class Derived3 : public Derived2{};

int main()
{
    Base* b[] = {new Base, new Derived1, new Derived2, new Derived3};
    for (auto p : b) delete p;
}