【问题标题】:Move semantic of shared_ptrshared_ptr 的移动语义
【发布时间】:2021-09-24 17:33:00
【问题描述】:

我刚开始学习智能指针,遇到了一个似乎与理论相矛盾的情况。 例如当我们使用 shared_ptr 并且如果调用复制语义时,对象共享所有权并且引用计数为 2。这没关系并且可以理解。 以代码为例。

 class Test {
    public:
    Test(){ cout << "Const" << "\n"; }

    void Disp(){
        cout << "Class Test()\n";
    }

    ~Test(){ cout << "Dest" << "\n"; }
 };

int main()
{
 Test *p = new Test();
 shared_ptr<Test> p1(p);
 shared_ptr<Test> p2(p1); // = make_shared<Test>(*p1);

 p1->Disp();
 p2->Disp();

}

输出很好:

Const
Class Test()
Class Test()
Dest

现在如果我尝试将语义移动为

int main()
{
 Test *p = new Test();
 shared_ptr<Test> p1(p);
 shared_ptr<Test> p2 = make_shared<Test>(*p1);

 p1->Disp();
 p2->Disp();

}

那么 p1 应该已经失去了所有权。因此 p1->Disp() 应该是有效的。因为 make_shared 将转移所有权以及重置 p1。但我仍然可以调用 p1->Disp() 并调用正确的函数。 请纠正我的理解。

谢谢。

【问题讨论】:

  • 第二个示例中没有移动语义,您正在创建一个新的 Test 对象
  • 那么示例 1 和示例 2 有什么区别,因为我们都是从第一个 shared_ptr 对象创建另一个 shared_ptr ?另外,那我怎么称呼移动语义?在这种情况下,第一个指针在第二个创建后变为空?
  • 在第一个示例中,您有一个 Test 实例,shared_ptr 都引用了它。在第二个中,您有两个 Test 实例,每个 shared_ptr 指的是不同的实例。
  • 明白。你能回答我第一条评论的第二和第三部分吗
  • @NihalKumar 您需要调用shared_ptr 的移动构造函数,使用make_shared() 不会调用它。如果你仔细想想,make_shared&lt;Test&gt;(*p1) 不能p1 转移所有权,因为它不知道p1 是什么从它那里窃取所有权。 *p1 指的是 p1 持有指针的对象,它不是 p1 本身。

标签: c++ c++11 shared-ptr boost-smart-ptr


【解决方案1】:

主要的误解是std::make_shared 不会移动旧对象的所有权。相反,您正在创建 Test 的第二个实例,新的 std::shared_ptr 引用该实例。

如果你真的想转移所有权,你需要明确地这样做,例如:

int main()
{
 Test *p = new Test();
 shared_ptr<Test> p1(p);
 shared_ptr<Test> p2(std::move(p1));

 // p1->Disp(); // No longer allowed, as p1 is now "empty"
 p2->Disp();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 2014-04-15
    • 2016-07-11
    • 1970-01-01
    相关资源
    最近更新 更多