C++拷贝构造函数实现浅拷贝共享shared_ptr是否属于不良实践?
结论
这种实现是非常常见的行业常规写法,是否合理、是否需要避免完全取决于你设计class A时约定的所有权语义,不存在“必须完全禁止”的说法。
适用场景(该写法合理的情况)
如果你的业务设计本来就要求多个A实例共享底层的B、C对象,那这个拷贝构造的实现是完全正确的,典型场景包括:
- 底层
B/C是只读不可变对象:比如全局配置、静态字典、只读缓存等,共享不会产生任何副作用,还能大幅降低拷贝开销,避免内存冗余 - 底层
B/C本身就是设计为多实例共享的资源:比如全局的日志服务实例、拼写检查器、公共硬件连接句柄等,这类资源本来就不需要每个A实例单独拷贝一份
这种场景下你如果强行拷贝B/C的实例,反而会违反业务逻辑,造成不必要的性能损耗。
不适用场景(该写法错误的情况)
如果你的业务约定每个A实例都要持有独立的B/C副本,修改新A实例关联的B对象不能影响原A实例,那这个实现就不符合要求,你需要改成深拷贝:
A::A(const A& a){ att1 = a.att1; att2 = a.att2; b_ptr = std::make_shared<B>(*a.b_ptr); // 假设B支持拷贝构造 c_ptr = std::make_shared<C>(*a.c_ptr); // 假设C支持拷贝构造 }
如果B/C是多态类型,建议给基类实现clone()虚函数来完成深拷贝,避免切片问题。
使用注意事项
如果采用共享指针的拷贝实现,需要额外注意两个问题:
- 线程安全:如果多线程环境下会修改共享的
B/C对象,需要自行加锁保护,避免数据竞争 - 循环引用:如果
B/C内部也持有指向A的shared_ptr,会形成循环引用导致内存泄漏,这种情况要把内部的指针改为weak_ptr
内容的提问来源于stack exchange,提问作者Chap
相关产品推荐
相关产品推荐

