gpt4 book ai didi

c++ - 无法使用类型为 'Parent' 的表达式初始化类型为 'Derived' 的对象参数

转载 作者:行者123 更新时间:2023-11-30 04:48:22 27 4
gpt4 key购买 nike

我正在实现一个简单的层次结构:System 和 Device 将是两个基类。系统有设备。然后我会有一个从系统派生的网络,它将有计算机。计算机派生自系统和设备。最后,计算机有各种设备,如 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() 有一个错误,因为不能用 Computer 类型的表达式初始化 System 类型的对象参数。我不完全确定这意味着什么,因为该函数是从 Computer 类调用的,它是一个设备,因此它应该可以访问父级的 addDevice()。该函数的参数是一个设备。

同样令人困惑的是我的 Network 类,其中函数 addComputer() 使用同一组指令没有错误。

谁能解释一下我的设计有何缺陷?

最佳答案

今天,当我正在编写派生类的代码时,这条错误消息突然出现,在我的例子中,关键是派生类——就在那一刻——未实例化。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 完整,从而可以实例化 Derivedobjects),代码将编译干净。

这里有两个可能的教训:

  • 完成您开始的工作。如果我没有将 SubType 的模拟完成一半,就不会出现这种情况。
  • 如果 linter 令人困惑,请查看构建的完整错误输出。

1 特别是我声明了一个成员,其中我还没有覆盖继承的抽象虚方法。

关于c++ - 无法使用类型为 'Parent' 的表达式初始化类型为 'Derived' 的对象参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55856187/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com