如何理解智能指针的底层指针地址?

Posted

技术标签:

【中文标题】如何理解智能指针的底层指针地址?【英文标题】:How to understand the underlying pointer address of a smart pointer? 【发布时间】:2019-12-13 13:09:01 【问题描述】:

我正在攻读 Udacity 的 C++ 纳米学位,讲座中有一些关于智能指针的内容,我认为这是一个错误,或者我遗漏了一些东西。 考虑以下示例:

#include <iostream>
#include <memory>
#include <string>

class MyClass

private:
    std::string _text;

public:
    MyClass() 
    MyClass(std::string text)  _text = text; 
    ~MyClass()  std::cout << _text << " destroyed" << std::endl; 
    void setText(std::string text)  _text = text; 
;

int main()

    // create unique pointer to proprietary class
    std::unique_ptr<MyClass> myClass1(new MyClass());
    std::unique_ptr<MyClass> myClass2(new MyClass("String 2"));

    // call member function using ->
    myClass1->setText("String 1");

    // use the dereference operator * 
    *myClass1 = *myClass2;

    ---This is the part I don't understand---
    // use the .get() function to retrieve a raw pointer to the object
    std::cout << "Objects have stack addresses " << myClass1.get() << " and " << myClass2.get() << std::endl;

    return 0;

我是这样理解这个例子的: 他们使用unique_ptr's get method 来获取指向托管数据的指针,托管数据分配在堆上。所以这个地址应该是一个堆地址,而不是内部指针所在的堆栈地址。 (智能指针内部原始指针的堆栈地址不应该从外部访问?)

对这段代码的官方解释是:“很明显,两个指针在堆栈上的地址不同,即使在将内容从 myClass2 复制到 myClass1 之后也是如此。”

但它不应该这样说:“两个指针仍然指向它们各自的堆地址,只有数据已从一个地址复制到另一个地址”?

【问题讨论】:

是的,.get() 不会返回堆栈地址(除非你做了一些非常时髦的事情)。 myClass1.get() 不是任何东西的堆栈地址。我不确定他们为什么会提到堆栈地址。它们几乎不相关。 这让我感到惊讶。所以 cout 中的文字也没有意义。 【参考方案1】:

正确。 unique_ptr objects 有不同的堆栈地址,它们也指向不同的堆地址。

执行myClass1.reset(myClass2.get()) 之类的操作会使两个unique_ptr 对象都指向同一个堆地址,这严重违反了unique_ptr 不变量。

【讨论】:

以上是关于如何理解智能指针的底层指针地址?的主要内容,如果未能解决你的问题,请参考以下文章

技术分享会之——智能指针

C++|深入理解智能指针

动态内存与智能指针

如何使用智能指针跟踪类的对象?

[易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

从源码理解智能指针—— shared_ptrweak_ptr