c++ - 在构造函数中被删除后继续执行

标签 c++

我在检查一些代码时遇到了以下场景。它工作正常,但对我来说这听起来像是未定义的行为,但我不知道要搜索什么以及如何证明它。

#include <memory>
#include <functional>
#include <string>
#include <iostream>

class Child
{
public:
    Child()
    {
        std::cout << "Child created\n";
    }
    ~Child()
    {
        std::cout << "Child is dead\n";
    }
};

class Parent
{
    std::unique_ptr<Child> m_child;
public:
    using Callback = std::function<void()>;
    Parent(const Callback& killMe)
    {
        std::cout << "Parent created\n";
        killMe();
        m_child = std::make_unique<Child>();
    }

    ~Parent()
    {
        std::cout << "Parent is dead\n";
    }
};

class GrandParent
{
    std::unique_ptr<Parent> m_child;
public:
    GrandParent()
    {
        m_child = std::make_unique<Parent>([this]() { KillChild(); });
    }

    void KillChild()
    {
        m_child.reset();
    }
};

int main()
{
    {
        GrandParent gp;
    }
    return 0;
}

我预计 Parent 在创建 Child 之前被杀死,但显然情况并非如此,我在多个编译器上尝试过并总是得到以下输出:

Parent created
Child created
Parent is dead
Child is dead

最佳答案

代码没有 UB 只是因为它没有按预期工作。

    m_child = std::make_unique<Parent>([this]() { KillChild(); })

这里

  1. 构造了Parent的实例
    • 调用 killMe() 调用 KillChild()
    • KillChild() 调用 m_child.reset(),它什么都不做,因为 m_child 是空的
  2. 然后 m_child 被赋值

如果它按预期工作,您将在 killMe() 之后获得释放后使用:

killMe();
m_child = std::make_unique<Child>(); // is actually this->m_child = , but *this* is gone now

关于c++ - 在构造函数中被删除后继续执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59191675/

相关文章:

c++ - QT多层窗口

C++ - 如何键入别名、typedef 或包装 boost::variant?

C++ Boost Asio 简单聊天教程

C++编程迭代和递归

c++ - QPainter 保存状态

c++ - 稀疏矩阵上的 block 操作 - Eigen Toolbox - C++

c++ - 为什么引用在 C++ 中不可重新安装

具有预增量 : With or without parentheses is the same? 的 C++ 箭头运算符

c++ - 什么时候可以安全且轻松地将引用变量用作别名?

c++ - 如何使用 std::ends 覆盖 std::ostringstream 中的字符串?