You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类构造函数创建线程:对象与指针实例化行为差异答疑

问题分析与解决方案

嘿,我来帮你捋捋这个问题的核心原因,其实是对象生命周期和线程等待逻辑出了问题,咱们一步步拆解:

为什么栈对象t能正常执行foo()?

当你创建栈对象test t;时,它的生命周期由C++编译器自动管理——main()函数执行完毕退出前,会自动调用t的析构函数。你的析构函数里写了m_thread.join();,这会让主线程等待子线程完成foo()的执行后再继续,所以foo()的输出能正常显示出来。

为什么堆对象t1的foo()完全不执行?

你用new创建的堆对象,生命周期是由你手动控制的:

  • 你没有调用delete t1;来销毁这些堆对象,所以它们的析构函数永远不会被执行,析构里的join()也就不会触发。
  • 当main()函数返回时,进程会直接终止,操作系统会强制杀死进程内的所有线程——这时候你的子线程可能还没来得及执行到cout输出的代码,就被终止了,自然看不到任何输出。

另外,你的代码里还有一个编译错误:main()里连续两次定义了test *t1,这是C++语法不允许的,得改成不同的变量名(比如t1和t2),或者避免重复定义。

修正后的代码示例

我们只需要手动销毁堆对象,让析构函数执行join(),就能让foo()正常输出:

#include <iostream>
#include <thread>
using namespace std;

void foo() {
    cout << "foo.. foo.. foo.." << endl;
}

class test {
public:
    test();
    ~test();
private:
    std::thread m_thread;
};

test::test() {
    this->m_thread = std::thread(foo);
}

test::~test() {
    // 先检查线程是否可join,避免重复join的问题
    if (m_thread.joinable()) {
        m_thread.join();
    }
}

int main() {
    test t; // foo()函数执行
    
    test *t1 = new test; 
    delete t1; // 手动销毁堆对象,触发析构和join
    
    test *t2 = new test();
    delete t2; // 同样手动销毁
    
    return 0;
}

额外建议:使用智能指针避免内存泄漏

如果你不想手动管理delete,可以用std::unique_ptr或者std::shared_ptr来自动管理堆对象的生命周期,这样就不用担心忘记销毁对象的问题了:

#include <memory> // 记得包含头文件

int main() {
    test t;
    
    auto t1 = make_unique<test>(); // 自动销毁
    auto t2 = make_shared<test>(); // 自动销毁
    
    return 0;
}

内容的提问来源于stack exchange,提问作者Surya Pratap Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:08:57