在C ++类中使用传递引用和成员初始化列表时会发生什么?

时间:2017-09-24 21:18:03

标签: c++ class

好的,所以我有一个大的矢量说

vector<vector<vector<int>>> 

10000×10000乘10000.

我有一个类,它有一个像私有成员变量的载体:

class foo {
private:
vector<vector<vector<int>>> myvector
};

我的类有一个构造函数,它使用pass by reference和initializer list:

foo(vector<vector<vector<int>>> &myvector_in) : myvector(myvector_in);

我想知道在内存使用方面究竟发生了什么。私有myvector是与最初声明的那个相同,还是副本。

基本上,我想知道内存中是否有两个版本的myvector。

谢谢!

3 个答案:

答案 0 :(得分:1)

这是钓鱼梢。

相当容易回答自己。将myvector_in的[0] [0] [0]设置为已知值。调用构造函数并在其中也将[0] [0] [0]但myvector设置为不同的值。返回构造函数后,打印myvector_in的内容。如果它与原始集合相同,则必须断定两个向量是不同的实体,因此将一个向量复制到另一个向量中。如果它们是相同的,那么你可以得出它们实际上是相同的实例。

你也可以打印地址,以便更好地了解它是什么。

我必须指出,你原来问题中提到的内存要求是在超级计算机领域,你有一个吗?

答案 1 :(得分:0)

您有vector<vector<vector<int>>>类型的成员,并使用其他vector<vector<vector<int>>>初始化该成员。怎么可能不在内存中存储两次所述数据?这更多的是逻辑问题,而不是c ++问题。

替代

您可以将指针vector<vector<vector<int>>>*或引用vector<vector<vector<int>>>&存储到相应类成员中的向量中。或者使用其中一个智能指针来执行此操作。在任何一种情况下,对内存管理的一些认真思考都是一个好主意。

或者您使用移动构造函数,它正在移动成员向量中的传入向量。

using vec = std::vector<std::vector<std::vector<int>>>;

class foo {
public:
    foo() = delete;
    foo(const vec&) = delete;
    foo(vec&& myvector_in) : myvector(std::move(myvector_in)) {};
private:
    vec myvector;
};

当然,这会使传递给构造函数的参数变得毫无用处,但这是你想要的非复制的一个微不足道的结果。

如果您首先使用std :: move将其转换为右值,则可以将向量传递给该构造函数。

foo my_foo(std::move(test));

答案 2 :(得分:0)

在C ++ 11(及更新版本)中解决此问题的简单方法是接受构造函数参数按值

struct foo {
  using vec=std::vector<std::vector<std::vector<int>>>;  // from DrSvanHay
  foo(vec v) : myvector(std::move(v)) {}
private:
  vec myvector;
};

令人惊讶的是,这实际上最小化了副本:

  1. 如果客户端有vector cv;cv会被复制到参数v中,但完成后需要该副本cvfoo::myvector
  2. 如果客户通过std::move(cv),则cv会被移至v并且没有副本。
  3. 如果客户端通过make_vector(...),则参数v将从返回值(或在C ++ 17中is the return value)进行初始化。
  4. (在所有这些情况下,v当然会转移到foo::myvector。)