在 C++ 中使用 shared_ptr 的指针的意外行为

Posted

技术标签:

【中文标题】在 C++ 中使用 shared_ptr 的指针的意外行为【英文标题】:Unexpected behavior of pointer to pointer using shared_ptr in C++ 【发布时间】:2015-12-01 02:01:24 【问题描述】:

在使用智能指针时,我对 C++ 中指向指针的行为感到困惑。

在下面的可编译代码示例中,您可以看到重新分配原始指针 pA 会影响指向指针 ppA 的指针,但在使用 std::shared_ptr 时情况并非如此。这似乎是非常违反直觉的行为。

#include <iostream>
#include <memory>

using namespace std;

int main() 

    // compare the functionality of raw and smart pointers
    int* pA = new int(1);
    int* pB = new int(2);
    shared_ptr<int> pAsmart(new int(1));
    shared_ptr<int> pBsmart(new int(2));

    // pointer to a pointer
    int** ppA = &pA;
    shared_ptr< shared_ptr<int> > ppAsmart = make_shared< shared_ptr<int> >(pA);

    cout << **ppA << endl; // prints 1
    cout << **ppAsmart << endl; // prints 1

    pA = pB;
    pAsmart = pBsmart;

    cout << **ppA << endl; // prints 2
    cout << **ppAsmart << endl; // prints 1 (huh?)



【问题讨论】:

那是因为ppAsmart 不指向pA 【参考方案1】:

shared_ptr&lt;shared_ptr&gt; 与指针指向不同。 ppAsmart 保存 make_shared() 返回的原始 shared_ptr。你没有做任何事情让ppAsmart指向其他任何东西,所以它仍然持有一个shared_ptr&lt;int&gt;,它仍然指向原始pA对象,其值为1。创建ppAsmart之后,你就是重新分配pA 以指向原始pB 对象,其值为2,而ppA 仍指向pA 变量,因此取消引用ppA 将获得值为2 的原始pB 对象. 但是ppAsmart 仍然指向原始的pA 对象,其值为1。它并不像ppA 那样指向pA 变量本身。

【讨论】:

我明白了,你说的很对。事实上,在我看来,涉及pAsmartpBsmart 的行在这段代码中什么也没做。在这种情况下,如何仅使用智能指针获得指针对指针的功能? 智能指针并非设计为以这种方式使用。你真正想要完成什么? 我最终试图理解 quantlib 库中实现的句柄模式。事实证明,quantlib 中的各种构造函数接受句柄(基本上是指针到指针的智能等价物),请参见 p。 dl.dropboxusercontent.com/u/13584583/qlbook/appendixA.pdf 中的 237 个了解详情【参考方案2】:

ppAsmart指向一个新对象,该对象指向pA的对象;特别是它不指向pA。它保持不变。试着用指针和指向对象来描绘一个图表,你会看到。

shared_ptr< shared_ptr<int> > ppAsmart = make_shared< shared_ptr<int> >(pA);

【讨论】:

以上是关于在 C++ 中使用 shared_ptr 的指针的意外行为的主要内容,如果未能解决你的问题,请参考以下文章

c++ 智能指针 shared_ptr 在多态上的使用

C++智能指针

C++智能指针

C++智能指针之shared_ptr与右值引用(详细)

C++智能指针之shared_ptr与右值引用(详细)

C++智能指针之shared_ptr与右值引用(详细)