能否创建对象的智能指针并将其传入该对象的构造函数?
能否将对象的智能指针传入自身构造函数?
当然可以实现让对象内部持有指向自身的智能指针,但不能直接像你写的那样在构造时传入未初始化的智能指针——因为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.
相关产品推荐
相关产品推荐

