
在C中智能指针std::shared_ptr可以用于类的成员变量来自动管理动态内存的生命周期。当我们将shared_ptr作为类的成员时它会确保在对象销毁时自动释放资源。实现构造函数时我们需要考虑如何初始化类成员的shared_ptr以及如何管理对象的所有权和资源的生命周期。下面是一个示例展示如何在类中使用std::shared_ptr作为成员变量并实现不同类型的构造函数C代码示例#include iostream #include memory #include string class MyClass { public: // shared_ptr 成员变量 std::shared_ptrstd::string name; // 默认构造函数 MyClass() : name(std::make_sharedstd::string(Default Name)) { std::cout Default constructor called: *name std::endl; } // 参数化构造函数 MyClass(const std::string new_name) : name(std::make_sharedstd::string(new_name)) { std::cout Parameterized constructor called: *name std::endl; } // 拷贝构造函数 (shared_ptr 默认会处理引用计数) MyClass(const MyClass other) : name(other.name) { std::cout Copy constructor called: *name std::endl; } // 移动构造函数 (转移 shared_ptr 的所有权) MyClass(MyClass other) noexcept : name(std::move(other.name)) { std::cout Move constructor called: (name ? *name : null) std::endl; } // 析构函数 ~MyClass() { std::cout Destructor called: (name ? *name : null) std::endl; } // 成员函数显示 name void display() const { std::cout My name is: *name std::endl; } }; int main() { std::cout Creating obj1 using default constructor std::endl; MyClass obj1; // 默认构造函数 std::cout \nCreating obj2 using parameterized constructor std::endl; MyClass obj2(Custom Name); // 参数化构造函数 std::cout \nCreating obj3 by copy constructing from obj2 std::endl; MyClass obj3 obj2; // 拷贝构造函数 std::cout \nCreating obj4 using move constructor std::endl; MyClass obj4 std::move(obj2); // 移动构造函数 std::cout \nCalling display function on obj1, obj3, and obj4: std::endl; obj1.display(); obj3.display(); obj4.display(); return 0; }解释1、成员变量std::shared_ptrstd::string name;属性说明变量名name类型std::shared_ptrstd::string— 指向std::string的共享智能指针作用管理一个字符串对象的生命周期多个MyClass对象可以共享同一个字符串内存位置对象本身在栈上8/16字节实际字符串数据在堆上2、默认构造函数MyClass() : name(std::make_sharedstd::string(Default Name)) { std::cout Default constructor called: *name std::endl; }属性说明触发时机无参创建对象MyClass obj1;初始化列表用make_shared在堆上创建字符串Default Name赋值给name引用计数初始为 1只有当前对象持有输出Default constructor called: Default Name3、参数化构造函数MyClass(const std::string new_name) : name(std::make_sharedstd::string(new_name)) { std::cout Parameterized constructor called: *name std::endl; }属性说明触发时机传入字符串创建对象MyClass obj2(Custom Name);初始化列表用传入的new_name在堆上创建字符串引用计数初始为 1输出Parameterized constructor called: Custom Name4、拷贝构造函数MyClass(const MyClass other) : name(other.name) { std::cout Copy constructor called: *name std::endl; }属性说明触发时机用一个已有对象创建新对象MyClass obj3 obj2;操作name(other.name)— 复制shared_ptr不复制字符串本身引用计数从 1 变为 2obj2 和 obj3 共享同一字符串性能O(1)无深拷贝开销输出Copy constructor called: Custom Name内存示意图 obj2.name ──┐ ├──► 堆上字符串 Custom Name (引用计数2) obj3.name ──┘5、移动构造函数MyClass(MyClass other) noexcept : name(std::move(other.name)) { std::cout Move constructor called: (name ? *name : null) std::endl; }属性说明触发时机用右值创建对象MyClass obj4 std::move(obj2);操作name(std::move(other.name))— 转移shared_ptr所有权引用计数保持不变不增加因为只是指针转移other.name被置为nullptr悬空不再持有字符串性能O(1)只是指针赋值输出Move constructor called: Custom Name移动前obj2.name ──► 堆上字符串 Custom Name (引用计数1) 移动后obj2.name nullptr obj4.name ──► 堆上字符串 Custom Name (引用计数1)6、析构函数~MyClass() { std::cout Destructor called: (name ? *name : null) std::endl; }属性说明触发时机对象离开作用域main 函数结束操作shared_ptr自动减少引用计数释放条件引用计数变为 0 时自动delete堆上字符串输出示例Destructor called: Custom Name或Destructor called: null析构函数顺序main结束时逆序对象创建顺序obj1 → obj2 → obj3 → obj4 析构顺序 obj4 → obj3 → obj2 → obj1 引用计数变化 - obj4 析构字符串 Custom Name 计数 1→0释放 - obj3 析构字符串 Custom Name 计数 1→0释放注意obj3 和 obj4 共享的是不同字符串因为 obj4 是从 obj2 移动来的 - obj2 析构name 已经是 nullptr被移动走了输出 null - obj1 析构释放 Default Name7、显示函数void display() const { std::cout My name is: *name std::endl; }属性说明const 修饰不修改成员变量可对 const 对象调用解引用*name获取shared_ptr管理的字符串对象安全性假设name非空构造时总是初始化输出示例Creating obj1 using default constructor Default constructor called: Default Name Creating obj2 using parameterized constructor Parameterized constructor called: Custom Name Creating obj3 by copy constructing from obj2 Copy constructor called: Custom Name Creating obj4 using move constructor Move constructor called: Custom Name Calling display function on obj1, obj3, and obj4: My name is: Default Name My name is: Custom Name My name is: Custom Name Destructor called: Custom Name Destructor called: Custom Name Destructor called: Default Name Destructor called: null关键点1、std::shared_ptr 的拷贝与移动行为std::shared_ptr 支持引用计数机制因此对 shared_ptr 的拷贝会增加引用计数保证内存管理不会出现问题。移动构造函数通过 std::move 实现所有权的转移而不是进行深拷贝优化了性能。2、智能指针的内存管理shared_ptr 会自动管理指向对象的生命周期无需手动 delete避免内存泄漏和双重删除的问题。3、析构函数的自动释放资源当 shared_ptr 的最后一个拷贝离开作用域时它会自动释放资源。这意味着你不需要担心内存泄漏问题。总结在使用std::shared_ptr作为类的成员变量时我们可以通过正确实现不同的构造函数确保类的对象可以在不同的情况下正确初始化和管理资源。同时std::shared_ptr的拷贝构造函数、移动构造函数以及析构函数会自动处理内存的管理减少了出错的机会。