buz*_*sin 1 c++ diamond-problem c++17
#include <iostream>
#include <cassert>
struct MyEnum {
enum valid { CASE1, CASE2, DEFAULT };
valid value;
MyEnum(valid value = DEFAULT) : value(value) {}
};
class Base {
protected:
MyEnum value;
public:
Base() = default;
Base(MyEnum value) : value(value) {
std::cout << "Base::Base(MyEnum).\n";
}
};
class ReadableBase : public virtual Base {
public:
ReadableBase() = default;
ReadableBase(MyEnum value) : Base(value) {
std::cout << "ReadableBase::ReadableBase(MyEnum).\n";
}
public:
MyEnum read() { return value; }
};
class WriteableBase : public virtual Base {
public:
WriteableBase() = default;
WriteableBase(MyEnum value) : Base(value) {
std::cout << "WriteableBase::WriteableBase(MyEnum).\n";
}
public:
void write(MyEnum value) { this->value = value; }
};
class ReadWriteBase : public ReadableBase,
public WriteableBase {
public:
ReadWriteBase() = default;
ReadWriteBase(MyEnum value) : ReadableBase(value), WriteableBase(value) {}
};
int main(int, char*[]) {
// Incorrectly initialised with value = MyEnum::valid::DEFAULT
ReadWriteBase rw(MyEnum::valid::CASE1);
// Everything is okay now.
rw.write(MyEnum::valid::CASE2);
}
Run Code Online (Sandbox Code Playgroud)
正如所演示的,尽管ReadWriteBase派生类接受MyEnum具有等效值 的,但程序报告和0 (= MyEnum::valid::CASE1)的值是。这似乎是因为根本没有被调用。ReadableBase::valueWriteableBase::value2 (= MyEnum::valid::DEFAULT)Base::Base(MyEnum)
assert(rw.ReadableBase::value == MyEnum::valid::DEFAULT); // true
assert(rw.WriteableBase::value == MyEnum::valid::DEFAULT); // true
assert(rw.Base::value == MyEnum::valid::DEFAULT); // true
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种情况?我该如何正确地做到这一点?
额外问题:有没有更好的方法来解决这个问题?
为什么会出现这种情况?我该如何正确地做到这一点?
虚拟基应该在最派生的类中初始化,所以应该是
class ReadWriteBase : public ReadableBase,
public WriteableBase {
public:
ReadWriteBase() = default;
ReadWriteBase(MyEnum value) :
Base(value),
ReadableBase(value), // possibly ReadableBase()
WriteableBase(value) // possibly WriteableBase()
{}
};
Run Code Online (Sandbox Code Playgroud)