我正在实现一个简单的层次结构: System 和 Device 将是两个基类。一个系统有设备。然后我将拥有一个从 System 派生的网络,该网络将拥有计算机。计算机源自系统和设备。最后,计算机具有各种设备,例如 CPU、内存等。计算机是设备的原因是因为网络是系统,系统存储设备。计算机是系统的原因是因为它存储设备(CPU、内存等)
无论如何,到目前为止我的实现:
class Device {
public:
explicit Device(unsigned property): property(property) {}
friend void swap(Device &first, Device &second) {
using std::swap;
swap(first.property, second.property);
}
Device& operator=(Device other) {
swap(*this, other);
return *this;
}
private:
Device() = default;
unsigned property;
};
class System {
public:
explicit System(const string &name): name(name) {}
friend void swap(System &first, System &second) {
using std::swap;
swap(first.name, second.name);
swap(first.devices, second.devices);
}
System& operator=(System other) {
swap(*this, other);
return *this;
}
protected:
void addDevice(Device b1) {
devices.push_back(b1);
}
private:
vector<Device> devices;
string name;
};
class Computer: public System, public Device {
public:
Computer(unsigned property, const string& name): System(name), Device(property) {}
Computer& addAddress(const string &address) {
addresses.emplace_back(address);
return *this;
}
Computer& addComponent(Device newDevice) {
System::addDevice(newDevice); //error
return *this;
}
private:
vector<const string> addresses;
};
class Network: public System {
public:
Network(const string& name): System(name) {}
Network& addComputer(Device newComputer) {
System::addDevice(newComputer); //no error
return *this;
}
};
class CPU: public Device {
public:
CPU(unsigned coreCount, unsigned frequency): Device(coreCount), frequency(frequency) {}
private:
unsigned frequency;
};
计算机的 addComponent() 有错误,因为 cannot initialize object parameter of type System with an expression of type Computer
。我不完全确定这意味着什么,因为该函数是从计算机类调用的,这是一个设备,因此它应该可以访问父级的 addDevice()。该函数的参数是一个设备。
我的 Network 类也令人困惑,其中函数 addComputer() 使用相同的指令集没有错误。
有人可以解释我的设计有什么缺陷吗?
原文由 Le Nguyen Duy Anh 发布,翻译遵循 CC BY-SA 4.0 许可协议
今天,当我正在编写派生类的过程中时,这条错误消息突然出现在我面前,就我而言,关键是派生类——就在那一刻——不可实例化。 1
一旦我在派生类上取得足够的进展以使其实例化,错误就会消失。
原因
您键入以调用基类的派生调用当前是不可实例化的。
示范
考虑以下具有两个继承关系的代码。
尝试编译它
你会收到反馈
如果你同时看到这三个,你知道从哪里开始,但是如果你使用 clang 作为 linter(就像许多 IDE 一样),那么你可能会看到第三个(出现在
Base::m();
行上,a完全有效的代码片段)在与前两个分离的上下文中。瞬间混乱。
如果您从代码的两个标记部分中删除注释(使
SubType
完整,从而可以实例化Derived
对象),代码编译干净。这里有两个可能的教训:
SubType
的类比,就不会出现这种情况。1特别是我有一个成员声明了一个我尚未覆盖继承的抽象虚拟方法的类型。