在传统的C++中,将值传递给函数和方法对于大型对象来说是很慢的,并且通常不赞成.相反,C++程序员倾向于传递引用,这更快,但它引入了围绕所有权的各种复杂问题,特别是围绕内存管理(如果对象是堆分配的)
现在,在C++ 11中,我们有Rvalue引用和移动构造函数,这意味着可以实现一个大的对象(比如一个std::vector),它可以通过值传入和传出函数.
那么,这是否意味着默认值应该是传递类型实例的值,例如std::vector和std::string?自定义对象怎么样?什么是新的最佳做法?
我看到某个地方有人决定复制一个对象并随后将其移动到一个类的数据成员的代码.这使我感到困惑,因为我认为移动的重点是避免复制.这是一个例子:
struct S
{
S(std::string str) : data(std::move(str))
{}
};
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
str?std::string吗?我有一个大型数据集(几千兆字节)存储在一个不适合QVector(max~2gb)的文件中,这个文件是写时复制的,不会受此影响.我将向量加载到内存中,如下所示:
std::vector<int> load()
{
std::vector<int> vec;
QFile file("filename");
file.open(QIODevice::ReadOnly);
QDataStream stream(&file);
stream >> vec; //using my implementation of QDataStream &operator>>(QDataStream &stream, std::vector<int> &v)
return vec;
}
Run Code Online (Sandbox Code Playgroud)
并将其传递给:
class Data
{
public:
Data(const std::vector<int> &data) :
d(data)
{
}
private:
std::vector<int> d;
};
Run Code Online (Sandbox Code Playgroud)
像那样:
Data data(load());
Run Code Online (Sandbox Code Playgroud)
现在,load()在向量中创建并填充文件中的数据.然后它按值返回,但我相信它应该由编译器优化,不要实际复制,vec而是将其移动到目标.
目标是私有成员,Data但我怀疑构造函数中的初始化列表可能实际上复制了向量而不是移动它,因为它不知道(或者它是什么?)它已经收到了对临时的const引用.
有没有办法保证矢量只会在构造后移动而不是在这种情况下复制?我怀疑使用std::move,std::forward或者改变的标志Data::Data()取r值的参考?