gpt4 book ai didi

c++ - 多重继承和unique_ptr销毁

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:52:27 27 4
gpt4 key购买 nike

我有经典的(可能有问题的)多重继承菱形方案。

  • B继承了A
  • C 继承了 A
  • D继承了C和B

我想要一个std::vector可以包含 CD对象,所以我将其设为 std::vector<C>这是D爸爸和它工作正常。

但是 当我使用:std::vector<std::unique_ptr<C>>然后我在破坏 vector 时出现段错误。

** glibc detected *** ./a.out: free(): invalid pointer: 0x0000000009948018***

为什么会有差异?对我来说,即使是第一次实现也是有问题的。

代码

#include <string>
#include <vector>
#include <memory>

class A
{
public:
A() = default;
};

class B : public virtual A
{
public:
B() = default;
};

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

class D : public B, public C
{
public:
D() = default;
};


int main()
{
{ // this crashes
std::vector<std::unique_ptr<C>> v;
std::unique_ptr<D> s1(new D());
v.push_back(std::move(s1));
std::unique_ptr<C> s2(new C());
v.push_back(std::move(s2));
}

{ // this is fine
std::vector<C> v;
D s1;
v.push_back(s1);
C s2;
v.push_back(s2);
}

return 0;
};

最佳答案

您应该将析构函数声明为虚拟的。否则,如果您的类 D 使用指向 C 的指针被删除,那么 ~C() 析构函数将被调用并且将错过清理。

另请注意,在您的第二部分(不使用 unique_ptr)中,您进行了一些对象切片。这意味着您正在将 D 类型的 s1 拷贝创建到类 C 的新对象中,因此您可能会丢失特定于D.

修改后的代码:

#include <string>
#include <vector>
#include <memory>

class A
{
public:
A() = default;
virtual ~A() {};
};

class B : public virtual A
{
public:
B() = default;
virtual ~B() {};
};

class C : public virtual A
{
public:
C() = default;
virtual ~C() {};
};

class D : public B, public C
{
public:
D() = default;
virtual ~D() {};
};


int main()
{
{ // this does not crashe anymore
std::vector<std::unique_ptr<C>> v;
std::unique_ptr<D> s1(new D());
v.push_back(std::move(s1));
std::unique_ptr<C> s2(new C());
v.push_back(std::move(s2));
}

{ // this is fine because you slice D into C, still that fine ?
std::vector<C> v;
D s1;
v.push_back(s1);
C s2;
v.push_back(s2);
}

return 0;
}

另见


注意事项

如评论中所述,如果将析构函数标记为虚拟,则每个派生类也将具有虚拟析构函数。把它写在任何地方都可以使它更明确。这是一个风格问题。

关于c++ - 多重继承和unique_ptr销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39124238/

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