我正在实现一个简单的层次结构:系统和设备将是两个基类。系统具有设备。然后,我将有一个从系统派生的网络,它将有计算机。计算机来自系统和设备。最后,计算机具有各种设备,如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;
};
由于cannot initialize object parameter of type System with an expression of type Computer
,计算机的addComponent()出错。我不完全确定这是什么意思,因为该函数是从Computer类(它是Device)调用的,因此它应该可以访问父级的addDevice()。函数具有的参数是设备。
我的Network类(其中函数addComputer()使用相同的指令集)没有错误也令人困惑。
有人可以解释我的设计有何缺陷吗?
答案 0 :(得分:0)
您不能拥有std::vector
基类实例并将派生实例保存到其中。使用指向向量中基类的指针,例如std::vector<std::shared_ptr<Device>>
答案 1 :(得分:0)
今天,当我正在对派生类进行编码的过程中,此错误消息为我弹出。在我的情况下,关键是派生类-就在那一刻-不可思议。 > 1
一旦我在派生类上取得足够的进展以实例化它,错误就会消失。
您正在键入的派生调用当前无法实例化。
请考虑以下具有两个继承关系的代码。
class Type {
public:
Type(){}
virtual ~Type() {}
virtual void m() = 0;
};
class SubType: public Type {
public:
SubType(): Type() {}
virtual ~SubType() {}
// virtual void m() override; // <== Important code commented out here
};
// void SubType::m() {} // <== and here
class Base {
public:
Base() {};
virtual ~Base() {}
virtual void m();
};
class Derived: public Base, public Type {
public:
Derived(): Base() {}
virtual ~Derived() override {}
virtual void m() override;
protected:
SubType m_troublesome; // <== Note member here has incomplete type when
// comments are in place
};
void Base::m() {}
void Derived::m() {
Base::m(); // <== Tricky error message on this line
}
尝试使用
进行编译$ clang --std=c++11 -Wall -pedantic -c test.cc
您会收到反馈
test.cc:34:13: error: field type 'SubType' is an abstract class
SubType m_troublesome;
^
test.cc:8:18: note: unimplemented pure virtual method 'm' in 'SubType'
virtual void m() = 0;
^
test.cc:42:11: error: cannot initialize object parameter of type 'Base' with an
expression of type 'Derived'
Base::m();
如果同时看到这三个,则知道从哪里开始,但是如果您将clang用作linter(就像许多IDE一样),那么您可能会看到第三个(在Base::m();
行中,隔离的完全有效的代码段)中的内容与前两个内容不同。
即时混乱
如果从代码的两个标记部分中删除注释(使SubType
完成并因此可以实例化Derived
对象),则代码将干净地编译。
SubType
的类比,那情况将永远不会发生。1 特别是我声明了一个成员,而该成员的类型尚未覆盖继承的抽象虚拟方法。