c++ - 通过引用 C++ 中的构造函数传递堆栈分配的值

标签 c++ reference initialization

我正在使用外部库,有些代码让我停下来。基本上,有一个在循环内(在堆栈上)分配的 vector 。然后该 vector 通过引用传递给某个对象的构造函数,并用于初始化对象的 vector 字段之一,该字段未声明为引用。新创建的对象是否持有对不再存在的东西的引用?或者这只是一种更有效的 vector 复制方式,在这种情况下,它被分配到堆栈上的事实没有区别吗?

这是一个最小的例子:

class Holder {
public:
    Holder(vector<int>& vref) : vec(vref) {}
    vector<int> vec;
}

Holder* MakeHolder() {
    vector<int> v {1, 2};
    return new Holder(v);
}

int main() {
    Holder *h = MakeHolder();
}

最佳答案

没有对已分离对象的引用,但我当然不会称其为“高效”。如果 ctor-initialiser 中没有 std::move,则必须复制 vector 。

你可以把 std::move 放在那里,但是 Holder 使用起来会有点困惑。

我个人会按值获取 vector ,因此调用作用域可以 std::move 进入它(或传递一个将自动执行此操作的临时值),然后 std: :move 构造函数参数到新成员中。这样一来,您实际上一直只有一个 vector 。

class Holder {
public:
    Holder(vector<int> vref) : vec(std::move(vref)) {}
    vector<int> vec;
}

Holder* MakeHolder() {
    vector<int> v {1, 2};
    return new Holder(std::move(v));  // Or just `return new Holder({1,2});`
}

int main() {
    Holder *h = MakeHolder();
}

并且,通过这种方式,如果您想保持原始 vector 处于事件状态(而不是移动),那也很好!只需将其传递进去,它就会被复制。事情将“正常工作”,而不需要真正知道构造函数代码中的内容(您只需要知道它需要一个值)。

我要更改的另一件事是引入 std::unique_ptr,因为您当前有内存泄漏:

class Holder {
public:
    Holder(vector<int> vref) : vec(std::move(vref)) {}
    vector<int> vec;
}

std::unique_ptr<Holder> MakeHolder() {
    return std::make_unique<Holder>({1,2});
}

int main() {
    auto h = MakeHolder();
}

(有些人会拼写 MakeHolder() 的返回类型 auto,但我不会。我认为了解您将要得到什么很重要。对于例如,否则你必须阅读代码才能知道结果的所有权语义是什么!它是原始指针吗?还有别的吗?)

关于c++ - 通过引用 C++ 中的构造函数传递堆栈分配的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51618428/

相关文章:

c++ - 如何将编译时元数据/行为添加到特定函数

c++ - 放置新的以获得动态大小

javascript - 将值设置为引用的 JavaScript 对象

java - 初始化图像

java - 获取 "Could not initialize class sun.security.ec.SunEC"如何继续?

c++ - 调整 native 窗口大小

c++ - 长整数的表示

c++ - 两个单独的指针可以引用同一个地址吗?如果是这样,我可以用任一指针更改该地址的值吗?

c++ - 假设引用作为指针传递是否有效

c - 静态结构初始化 C