通过 bases 初始化 derived 类

Initializing derived classes through bases

考虑:

struct V {
    V(int i) {
        std::cout << "initialized v" << '\n';
    }
};

struct A {
    A() {
        std::cout << "initialized a" << '\n';
    }
};

struct B : virtual V, virtual A {
    B(int i) :V{i} {
        std::cout << "initialized b" << '\n';
    }
};

class C : virtual V, virtual A {
public:
    C(int i) : V{i} {
        std::cout << "initialized c" << '\n';
    }
};

class D : virtual public B, virtual public C {
public:
    D(int i, int j) :V{i}, B{i}, C{j} {
        std::cout << "initialized d" << '\n';
    }
};

如果我在 main() 中初始化 D,像这样:

int main() {
    D* d = new D{3,3}; //ok
    B* b = new D{3,3}; //ok
    C* c = new D{3,3}; //undefined
    delete d;
    delete b;
    delete c;

}

但是如果我使用工厂,就像这样:

C* factory() {
    return new D{3,3};
}

int main() {
    factory(); //ok
}

我不明白为什么当我在 main() 中通过 C 初始化 D 时会导致未定义的行为,但当我使用其他函数时工作正常。 C有什么问题?不就是和B一样吗?

编辑:所以我的代码在 this demo 上运行良好,正如我认为的那样。如果我的代码没有问题,是不是我的开发环境有问题?我正在使用最新的 mingw-w64 和 eclipse CPP。

你在所有错误的地方寻找不确定性。

delete b;
delete c;

这两行调用未定义的行为,通过删除派生的 class 对象(D)和指向基 class 的指针(B*C*) 没有虚拟析构函数。给他们一个(例如,将 virtual ~V() = default; 添加到 V),崩溃应该会消失。

这就是为什么验证您 post 此处的代码实际上 重现了 您在编译和 运行 时看到的崩溃的原因。如果一开始就有完整的代码,有人可能会在不到 5 分钟的时间内发现问题。相反,我们花了 45 分钟试图重现该问题。