#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:"Deferrd1":无法生成析构函数,因为基类析构函数不可访问或删除
警告 2警告 C4624:"派生 2":无法生成析构函数,因为基类析构函数不可访问或删除
警告3 警告 C4624:"Deferrd3":无法生成析构函数,因为基类析构函数不可访问或删除
错误4 错误 C2243:"类型转换":存在从"派生 1 *"到"基本 *"的转换,但无法访问
错误5 错误 C2243:"类型转换":从"派生 2 *"到"基本 *"的转换存在,但无法访问
错误6 错误 C2243:"类型转换":存在从"派生3 *"到"基本 *"的转换,但无法访问
警告7 警告 C4154:删除数组表达式;转换为提供的指针
8 智能感知:不允许转换为无法访问的基类"基">
9 智能感知:不允许转换为无法访问的基类"Dederd1">
10 智能感知:不允许转换为无法访问的基类"Derived2">
问题 1
将析构函数放在Base
的public
部分中。
class Base {
virtual ~Base() = default;
};
相当于:
class Base {
private:
virtual ~Base() = default;
};
将其更改为:
class Base {
public:
virtual ~Base() = default;
};
问题 2
Base* b[] = {new Base, new Derived1, new Derived2, new Derived3};
使用 new
运算符构造对象三次。您需要调用delete
三次 - 每个指针一次。
而不是
delete[] b;
用
delete b[0];
delete b[1];
delete b[2];
问题 3
为了能够使用
Base* p = new Derived1;
你必须使Base
成为Derived1
的public
基类,而不是protected
。
改变
class Derived1 : protected Base {};
class Derived2 : protected Derived1{};
class Derived3 : protected Derived2{};
自
class Derived1 : public Base {};
class Derived2 : public Derived1{};
class Derived3 : public Derived2{};
你有三个大问题:
首先,您滥用了delete[]
.当您使用 new []
分配数组时,将调用它。你还没有这样做。你需要遍历数组b
,在每个元素上调用delete
。
其次,您的Base
虚拟析构函数private
。派生类型需要可以访问它,因此请使其public
。
第三,所以DerivedN
是-Base
,需要使继承public
。否则,无法将指向派生对象的指针分配或初始化为指向 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;
}