【问题标题】:How do you instantiate smart pointer class members?你如何实例化智能指针类成员?
【发布时间】:2016-05-20 07:33:43
【问题描述】:

我最近一直在做一些非常狡猾的智能指针编程,因为我从来没有真正理解过移动构造函数、移动赋值等,因为像 MSDN 这样的地方给出的例子对我来说真的很复杂。我说的狡猾,我的意思是从字面上改变像 (lvalue + 0) 这样的操作来生成右值。

这是一个例子(我不擅长想出不深奥的场景):

class Person {
public:
    Person(int age) {
        age_ = age;
    }

private:
    int age_;
};

class Life {
public:
    Life(int age) {
        person_ = std::make_unique<Person>(age);
    }
private:
    std::unique_ptr<Person> person_;
};

年龄部分必须是右值,将其设为右值的正确方法是什么?我读过移动构造函数,但它们似乎是传递对象本身的右值引用?

编辑:另外,是否可以从类构造函数的成员初始化器列表中初始化智能指针成员?

【问题讨论】:

  • 对于与 Microsoft 产品无关的任何内容,我都会远离 MSDN。对于 C++ 信息,您应该将 cppreference.com 设为您的第一个停靠点。
  • "年龄部分必须是右值" age 是哪个部分?好吧,这是一个棘手的问题,因为 没有一个 必须是右值。我不知道你从哪里得到这个。如果你曾经使用(lvalue + 0) 创建一个右值,那么你做错了什么。
  • @NicolBolas 我正在使用的 IDE 警告我年龄 std::make_unique(age) 需要是一个右值表达式。但是,它编译得很好。 i.imgur.com/cFSbE4w.png
  • 这是什么 IDE?版本等请。
  • @Technik Empire 这是最新版本的 CLion。我也使用相同的代码在 Qt Creator 中收到错误。

标签: c++ smart-pointers member move-semantics


【解决方案1】:

您可以简单地执行以下操作,创建一个 Person 指针并将其分配给 unique_ptr:

class Life {
 public:
  Life(int age) : person_(new Person(age)) {}
  ...

【讨论】:

  • 感谢@keelar 的回答有没有办法在不使用成员初始化列表的情况下做到这一点?就像在构造函数体中一样?
  • @user3530525 std::unique_ptr&lt;T&gt;::reset(new T(...))
【解决方案2】:

首先,如果您需要来自左值的右值,直接的方法是 std::move(a),就是这样,但重要的是要注意您正在做什么。您正在将您的引用转换为左值,这意味着“如果您需要,您可以更改它,因为我不再需要该值”。

但是在您的情况下,它们是右值还是左值并不重要,因为您的 int 参数是一个通过复制传递的值,这与您有一个 Person(int& age) 或 Person(int&& age) 无关,什么不是你的情况。

但在这种情况下很重要

std::vector<int> b = ...
std::vector<int> a = b; //rvalue, means keep safe this data, I still need them 
std::vector<int> a = std::move(b);//lvalue, could be changed
std::vector<int> a = f(); //lvalue, could be changed since is just a temporary data

【讨论】:

    猜你喜欢
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多