C++ 重构代码以使用Boost共享指针

C++ 重构代码以使用Boost共享指针,c++,refactoring,shared-ptr,smart-pointers,C++,Refactoring,Shared Ptr,Smart Pointers,我用普通指针写了一个项目,现在我厌倦了手动内存管理 在重构过程中可以预见哪些问题 到目前为止,我已经花了一个小时将X*替换为shared\u ptr,用于自动管理内存的类型。然后我将dynamic\u cast更改为dynamic\u pointer\u cast。我仍然看到更多的错误(与NULL相比,将this传递给函数) 我知道这个问题有点模糊和主观,但我认为我可以从已经这样做的人的经验中获益 有什么陷阱吗 尽管在任何地方使用boost::shared_pointer都很容易,但您应该根据所

我用普通指针写了一个项目,现在我厌倦了手动内存管理

在重构过程中可以预见哪些问题

到目前为止,我已经花了一个小时将
X*
替换为
shared\u ptr
,用于自动管理内存的类型。然后我将
dynamic\u cast
更改为
dynamic\u pointer\u cast
。我仍然看到更多的错误(与
NULL
相比,将
this
传递给函数)

我知道这个问题有点模糊和主观,但我认为我可以从已经这样做的人的经验中获益


有什么陷阱吗

尽管在任何地方使用
boost::shared_pointer
都很容易,但您应该根据所有权语义使用正确的智能指针

在大多数情况下,默认情况下,您希望使用
std::unique_ptr
,除非所有权在多个对象实例之间共享

如果您遇到周期性的所有权问题,可以使用
boost::weak\u ptr
打破周期

还请记住,在传递共享的\u ptr时,出于性能原因(避免原子增量),您应该始终按常量引用传递它们,除非您确实希望将所有权授予其他实体

有什么陷阱吗

是的,根据墨菲定律,如果你盲目地用shared_ptr替换每个指针,结果会证明这不是你想要的,你将在接下来的6个月里寻找你引入的bug

在重构过程中可以预见哪些问题

内存管理效率低下,未使用的资源存储时间过长,内存泄漏(循环引用),引用计数无效(同一指针分配给多个不同的共享_指针)

不要盲目地用共享ptr替换所有内容。仔细研究程序结构,确保需要shread_ptr,并且它准确地表示您想要的内容

另外,请确保使用支持简单分支(git或mercurial)的版本控制,这样当您中断某些内容时,可以恢复到以前的状态或运行类似于“git对分”的操作来定位问题

显然,您需要将X*替换为shared_ptr


错。这取决于上下文。如果您有一个指向某个数组中间的指针(例如,像素数据操作),那么您将无法用共享的ptr替换它(您也不需要这样做)。只有在需要确保对象的自动解除分配时,才需要使用shared_ptr。对象的自动分配并不总是你想要的。

< P>如果你想支持Boost,你应该考虑如果你想要一个提升::SysDypPTR或者Booo::共享的_ptr是在类之间共享的资源,而作用域的_ptr听起来更像您想要的(至少在某些地方)。当内存超出作用域时,作用域\u ptr将自动删除内存

将共享的ptr传递给函数时要小心。shared_ptr的一般规则是按值传递,以便创建副本。如果通过引用传递,指针的引用计数将不会增加。在这种情况下,您可能会删除一段您希望保持活动状态的内存

但是,在某些情况下,您可能希望通过引用传递共享的\u ptr。也就是说,如果希望在不同的函数中分配内存。在这种情况下,只需确保调用者在其调用的函数的生命周期内仍然持有指针

void allocPtr( boost::shared_ptr< int >& ptrByRef )
{
    ptrByRef.reset( new int );
    *ptrByRef = 3;
}

int main()
{
    boost::shared_ptr< int >& myPointer;
    // I want a function to alloc the memory for this pointer.

    allocPtr( myPointer ); // I must be careful that I still hold the pointer
                           // when the function terminates

    std::cout << *ptrByRef << std::endl;
}
void allocPtr(boost::shared_ptr&ptrByRef)
{
ptrByRef.reset(新整数);
*ptrByRef=3;
}
int main()
{
boost::shared_ptr&myPointer;
//我想要一个函数来分配这个指针的内存。
allocPtr(myPointer);//我必须小心,我仍然拿着指针
//当函数终止时

std::cout我列出了涉及的步骤/问题。它们对我有用,但我不能保证它们是100%正确的

0)检查是否可能存在循环共享指针。如果存在,这是否会导致内存泄漏?在我的情况下,幸运的是,循环不需要中断,因为如果我有一个循环,循环中的对象是有用的,不应该被销毁。使用弱指针中断循环

1) 您需要将“most”
X*
替换为
shared_ptr
。在每次动态分配X之后,都会立即(仅?)创建一个共享_ptr。在所有其他时间,它都是复制构造的,或者是用空指针构造的(表示为NULL)。为了安全(但效率有点低),仅通过引用传递这些共享的\u ptr。无论如何,您可能从未通过引用传递过指针开始=>无需进行其他更改

2) 您可能在某些地方使用了
dynamic\u cast(y)
。将其替换为
dynamic\u pointer\u cast(y)

3) 无论在哪里传递
NULL
(例如,表示计算失败),都要传递一个空的共享指针

4) 删除相关类型的所有delete语句

5) 让您的基类B从
从\u this
启用\u shared\u。然后无论您在哪里传递
this
,传递,
从\u this()共享。\n如果函数需要派生类型,您可能必须执行静态强制转换。请记住,当您从\u this()调用
shared\u时
,某些
共享的\u ptr
必须已经拥有
。特别是,不要从类的构造函数中的\u this()
调用
共享的\u

我相信人们可以半自动化这个过程来获得语义上等价但不一定非常有效的代码

在这些步骤中,我经常使用正则表达式。大约花了3-4个小时。到目前为止,代码已经编译并正确执行。