如何通过move语义移动多个参数
How do I move multiple parameter via Move semantics?
让我们假设我有一个Object MeasurementValues,它有n个不同的指针(这个例子只显示了指向基元类型的指针,但也可能出现指向其他复杂对象的指针(。
class MesaurementValues {
private:
int *measurement_1;
double *measurement_2;
long long *measurement_3;
//..
float *measurement_n;
int noPointer;
}
我知道,无论如何,这个例子可能有点做作。我试图在我的代码中完全填充"五条规则"。
我必须吗
this.measurement_x = old.measurement_x ;// for all x = {1,..,n} ?
首先要注意,对于普通的旧数据类型(POD(成员,移动语义与复制语义相比没有优势,但当您的类包含其他类对象和/或数组时,它确实有优势。当你实现移动语义时,这意味着你有一个"移动构造函数"和/或"移动赋值运算符",在你的类中看起来像这样:
class MesaurementValues { private:
int *measurement_1;
double *measurement_2;
long long *measurement_3;
//..
float *measurement_n;
int noPointer;
//a couple different objects
someObject* pObj1;
differentObject* pObj2;
public:
MeasurementValues( MeasurementValues&& move ); //move-constructor
MeasurementValues& operator= (MeasurementValues&& move); //move-assignment
}
-假设您的类具有POD数据和类对象,并且-假设有很多变量需要转移:
MeasurementValues::MeasurementValues( MeasurementValues&& old) {
//copy plain-old-data over
measurement_1 = old.measurement_1;
measurement_2 = old.measurement_2;
//copy over values of the pointers
pObj1 = old.pObj1;
pObj2 = old.pObj2;
}
请记住,正如其他海报所说,只有当您的数据成员是其他可移动对象或动态分配的内存时,移动语义才有优势。
编辑:
中的指针必须变为"无效",因为它们已被移动。因此,我会将它们设置为null,以防止出现意外行为:
MeasurementValues::MeasurementValues( MeasurementValues&& old)
: measurement_1() //null...
//,...
{
//Swapping null into old...
std::swap(measurement_1, old.measurement_1);
//...
}
Do I have to
this.measurement_x = old.measurement_x ;// for all x = {1,..,n} ?
我会使用皮条客这个成语,并使用一个独特的指针。下面是一个详细的例子。请注意,您只需要使用Impl,并依赖于它的默认值(因为它不包含指针(。
#include <iostream>
#include <memory>
struct Moveable
{
public:
Moveable();
~Moveable();
Moveable(const Moveable& m);
Moveable& operator=(const Moveable& m);
Moveable(Moveable&& m);
Moveable& operator=(Moveable&& m);
int foo() const;
private:
struct Impl;
std::unique_ptr<Impl> pimpl_;
};
//Moveable.cpp
struct Moveable::Impl
{
Impl(): a(1), b(2), c(3), buffer(){}
int a, b, c;
char buffer[10000]; //Make it worth our while...
};
int Moveable::foo() const{ return pimpl_->a+pimpl_->b+pimpl_->c;}
Moveable::Moveable()
: pimpl_(new Impl)
{
std::cout << "Default " << (void*)this << std::endl;
}
Moveable::~Moveable()
{
std::cout << "Destruct " << (void*)this << std::endl;
//automagically...
}
Moveable::Moveable(const Moveable&m)
: pimpl_(new Impl(*m.pimpl_))
{
std::cout << "Copying " << &m << " to " << (void*)this << std::endl;
}
Moveable& Moveable::operator=(const Moveable& m)
{
std::cout << "Copy assign " << (void*)&m << " to " << (void*)this << std::endl;
*pimpl_ = *m.pimpl_; //Relying on their defaults...
}
Moveable::Moveable(Moveable&& m)
: pimpl_(move(m.pimpl_))
{
std::cout << "Moving " << (void*)&m << " to " << (void*)this << std::endl;
}
Moveable& Moveable::operator=(Moveable&& m)
{
pimpl_ = move(m.pimpl_);
std::cout << "Move assigning " << &m << " to " << (void*)this << std::endl;
}
int main()
{
Moveable x;
Moveable y(x); //Copying...
y = x; //Copying assign
y = Moveable(); //Default construct, then move assignment, destruct temp
Moveable z(std::move(y));
std::cout << "Calling foo " << z.foo() << std::endl;
return 0;
}
相关文章:
- MSVC将仅移动结构参数解释为指针
- 如果需要转换,我可以在读取参数的同时将其移动到另一个参数吗?
- 使用移动语义:右值引用作为方法参数
- 为什么参数在构造 std::thread 时移动两次
- 移动类的成员作为常量引用参数传递
- 当变量和参数名称匹配时,移动语义构造失败
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 移动构造函数中的默认参数
- 将参数传递给构造函数和成员函数时移动或复制
- 从函数返回元组时,将复制元组的参数,而不是移动元组参数
- C++具有移动语义的可变参数工厂会导致运行时崩溃
- 覆盖Qt的鼠标按下事件中断移动事件参数
- 在简单地移动参数时使用函数模板参数的优点
- 如果没有带有函数签名的 rvalue 参数,是否会执行 C++ 11 中的移动语义?
- x64 函数调用参数推送/移动顺序 (MSVC)
- 复制文件成功,移动文件失败,参数相同 - C++
- 从从可调用参数创建的线程对象参数移动构造 C++11 线程
- 将std::enable_if从参数移动到模板参数
- 将所有参数移动到 lambda
- 将参数移动到std::线程中