【问题标题】:Class destructor called twice when creating a shared_ptr创建 shared_ptr 时调用了两次类析构函数
【发布时间】:2017-05-24 09:36:48
【问题描述】:

当我为我的类创建共享 ptr 时,我遇到了类析构函数被调用两次的问题。

我正在尝试创建一个对象向量,每个对象都有一个构造函数和一个析构函数。

当我打电话时,例如:

std::vector<std::shared_ptr<ServoController>>  servos;
bool CreateServo(int id)
{
    std::shared_ptr<ServoController> servo = std::make_shared<ServoController>(ServoController(id));
    servos.push_back(servo);
}

ServoController 的构造函数被调用,然后 ServoController 的 Destructor 被调用,在它之前 push_back 函数甚至被调用。

然后,当我关闭应用程序时,会再次调用 ServoController 的析构函数。但是到目前为止,构造函数只被调用了一次(我在向量中只有 1 个对象)。至少它不应该让构造函数再次运行吗?

有没有什么办法可以为我的类制作一个向量,对于向量中的每个对象,构造函数都应该调用一次,而当从向量中删除对象或者向量是时,应该调用一次析构函数毁了?

谢谢, -D

【问题讨论】:

    标签: c++


    【解决方案1】:

    您正在使用此调用创建一个临时对象,这就是导致第一个(意外)析构函数调用的原因。

    std::make_shared<ServoController>(ServoController(id));
    

    事件的顺序是:

    • ServoController(id) 创建一个新的临时对象,该对象作为参数传递给 std::make_shared
    • std::make_shared&lt;ServoController&gt; 然后将临时对象转发给ServoController复制构造函数(这可能不是你想要的)。这就是为什么你的主构造函数只被调用一次。
    • 这会在堆上创建一个新对象(由shared_ptr 管理),它是您创建的临时对象的副本。
    • 然后立即销毁临时对象,这是第一次调用析构函数。

    你真正想要的是:

    std::make_shared<ServoController>(id);
    

    std::make_shared 将其参数直接转发给构造函数作为其模板参数。你不需要额外的构造函数调用。

    【讨论】:

    • 它可能是被调用的移动构造函数,而不是复制构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2015-02-25
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多