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

能否创建对象的智能指针并将其传入该对象的构造函数?

能否将对象的智能指针传入自身构造函数?

当然可以实现让对象内部持有指向自身的智能指针,但不能直接像你写的那样在构造时传入未初始化的智能指针——因为std::make_shared<Player>还没完成对象构造,player1此时还没有被赋值,根本没法把它作为参数传进去。

正确的做法是利用C++标准库提供的std::enable_shared_from_this基类,它专门用来解决这类"获取自身shared_ptr"的需求。下面是具体的实现步骤和示例:

1. 让类继承std::enable_shared_from_this

首先,你的Player类需要继承自std::enable_shared_from_this<Player>,这个基类会提供一个shared_from_this()方法,用来生成指向当前对象的std::shared_ptr。

2. 避免在构造函数中直接获取自身智能指针

注意:绝对不能在构造函数里调用shared_from_this()!因为当构造函数执行时,std::make_shared还没把对象和管理它的shared_ptr关联起来,此时调用这个方法会触发未定义行为(比如抛出异常或返回空指针)。

你需要在对象被shared_ptr完全管理后,再初始化内部的智能指针,或者在需要使用的时候临时调用shared_from_this()。

示例代码

方式一:构造完成后初始化内部shared_ptr

#include <memory>
#include <iostream>

class Player : public std::enable_shared_from_this<Player> {
private:
    std::shared_ptr<Player> self_ptr;
    int player_id;

public:
    // 构造函数只处理普通参数
    Player(int id) : player_id(id) {}

    // 构造完成后调用这个方法初始化内部指针
    void init_self_reference() {
        self_ptr = shared_from_this();
    }

    // 使用内部指针的示例方法
    void print_self_info() {
        if (self_ptr) {
            std::cout << "Player ID: " << self_ptr->player_id << "\n";
        }
    }
};

int main() {
    // 先创建shared_ptr管理对象
    auto player1 = std::make_shared<Player>(1001);
    // 再初始化内部的自身指针
    player1->init_self_reference();
    // 调用方法使用内部指针
    player1->print_self_info();
}

方式二:使用weak_ptr避免循环引用

如果你的场景可能出现循环引用(比如两个对象互相持有对方的shared_ptr),建议内部保存std::weak_ptr,这样可以避免内存泄漏:

#include <memory>
#include <iostream>

class Player : public std::enable_shared_from_this<Player> {
private:
    std::weak_ptr<Player> self_weak;
    int player_id;

public:
    Player(int id) : player_id(id) {}

    void init_self_reference() {
        self_weak = shared_from_this();
    }

    void print_self_info() {
        // 先lock()获取有效的shared_ptr,判断是否还存在
        if (auto self = self_weak.lock()) {
            std::cout << "Player ID: " << self->player_id << "\n";
        } else {
            std::cout << "Player object has been destroyed\n";
        }
    }
};

关键注意点

  • 只有当对象已经被std::shared_ptr管理时,shared_from_this()才有效。如果是在栈上创建的对象(比如Player p(1001);),调用这个方法会触发未定义行为。
  • 如果只是临时需要自身的shared_ptr,可以直接在方法里调用shared_from_this(),不需要提前保存成员变量。

内容的提问来源于stack exchange,提问作者George P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:42:54