c++ - 钻石物体的定义

标签 c++ c++17

假设我有一个菱形层次结构,如下面的代码所示。

class A {

public:
    A() {}
    int a = 3;
    virtual void aa() {}
};

class B : public virtual A {
public:
    B() : A() {}

    int b() { return 4; };
};

class C : public virtual A {
public:
    C() : A() {}
};

class D : public B, public C {
protected:
    int d = 45;

public:
    D() : B(), C() {}
};

我有一个这样的主要:
int main() {
    std::unique_ptr<A> a = std::make_unique<D>();
}

以上主要导致段错误。但是添加 a.release() to main 解决了段错误。这是为什么?

最佳答案

这是因为 A 中没有虚拟 Dtor。没有 Dtor,您可以看到在使用 GDB 运行时对象销毁中发生了段错误:

eddy@eddy-VirtualBox:~/deleteme$ g++ -std=c++14 -O0 -g test.cpp       
eddy@eddy-VirtualBox:~/deleteme$ gdb a.out
(gdb) run
Starting program: /home/eddy/deleteme/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff76f2c01 in __GI___libc_free (mem=0x555555769e88) at malloc.c:3123
3123    malloc.c: No such file or directory.
(gdb) bt
#0  0x00007ffff76f2c01 in __GI___libc_free (mem=0x555555769e88) at malloc.c:3123
#1  0x0000555555554f6d in std::default_delete<A>::operator() (this=0x7fffffffddd8, __ptr=0x555555769e88) at /usr/include/c++/7/bits/unique_ptr.h:78
#2  0x0000555555554e07 in std::unique_ptr<A, std::default_delete<A> >::~unique_ptr (this=0x7fffffffddd8, __in_chrg=<optimized out>)
    at /usr/include/c++/7/bits/unique_ptr.h:268
#3  0x0000555555554b68 in main () at test.cpp:33

向 A 类添加虚拟析构函数可以解决此问题:
public:
    A() {}
    int a = 3;
    virtual void aa() {}
    virtual ~A() = default;
};

关于c++ - 钻石物体的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60950126/

相关文章:

c++ - 等待文件存在且不被其他人占用

c++ - 提取头文件中的函数列表

C++数组问题

c++ - 如何检查类型是否可显式/隐式构造?

c++ - 结构化绑定(bind)中的 const 引用是否会延长分解对象的生命周期?

c++ - 如何避免隐式可转换类型

c++ - 如何在 UML 类图中表示纯虚函数?

c++ - SDL2 如何在第二台显示器上定位窗口?

c++ - 理解 C++ 中的命令

c++ - 根据 C++17 标准草案在 block 作用域中声明为 `extern` 的函数的链接