#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;不允许
答案 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;
}