在周末,我正在尝试刷新我的c ++技能并学习一些c ++ 11,我偶然发现了以下问题:我无法强制我的容器类正确使用移动构造函数:
我有一个构建器类,其定义如下:
class builder
{
...
container build() const
{
std::vector<items> items;
//... fill up the vector
return container(items); //should move the vector right? wrong!
//return container(std::move(items)); also doesn't work
}
}
Run Code Online (Sandbox Code Playgroud)
类item和容器,定义如下:
class container
{
public:
container(std:vector<item> items)
: items_(items) // always invokes copy constructor on vector, never move
{ }
container(container&& rhs)
{
...
}
...
private:
std::vector<item> items_;
}
class item
{
public:
//move .ctor
item(item && rhs);
item& operator=(item && rhs);
//copy .ctor
item(const item& rhs); //this gets called instead of move .ctor
item& operator=(const item& rhs);
...
}
Run Code Online (Sandbox Code Playgroud)
现在我的代码只使用了
builder my_builder;
...
auto result = my_builder.build();
Run Code Online (Sandbox Code Playgroud)
这导致每个项目首先被构建然后被复制...
我应该怎么写以下classess不复制项目?我应该回去使用标准指针吗?
GMa*_*ckG 22
您的代码应更改为:
container(std:vector<item2> items) // may copy OR move
: items_(std::move(items)) // always moves
{}
Run Code Online (Sandbox Code Playgroud)
一般来说:如果你想要自己的东西副本,那么在该参数列表上制作该副本并将其移动到需要的位置.让调用者决定是否要复制或移动现有数据.(换句话说,你就在那里.现在只需移动你的数据.)
另外:return container(std::move(items));.之前我没有提到过,因为我错误地认为所有局部变量都是在return语句中自动移动的,但只有返回的值是.(所以这实际上应该有效:return items;因为container构造函数不是explicit.)
为您编写了启用了模板移动的类。研究它,你会得到它。
/// <summary>Container.</summary>
class Container {
private:
// Here be data!
std::vector<unsigned char> _Bytes;
public:
/// <summary>Default constructor.</summary>
Container(){
}
/// <summary>Copy constructor.</summary>
Container(const Container& Copy){
*this = Copy;
}
/// <summary>Copy assignment</summary>
Container& operator = (const Container& Copy){
// Avoid self assignment
if(&Copy == this){
return *this;
}
// Get copying
_Bytes = Copy._Bytes; // Copies _Bytes
return *this;
}
/// <summary>Move constructor</summary>
Container(Container&& Move){
// You must do this to pass to move assignment
*this = std::move(Move); // <- Important
}
/// <summary>Move assignment</summary>
Container& operator = (Container&& Move){
// Avoid self assignment
if(&Move == this){
return *this;
}
// Get moving
std::swap(_Bytes, Move._Bytes); // Moves _Bytes
return *this;
}
}; // class Container
Run Code Online (Sandbox Code Playgroud)
我一直反对使用这样的值参数:
function(std:vector<item2> items)
Run Code Online (Sandbox Code Playgroud)
我总是使用:
function(const std:vector<item2>& items)
function(std:vector<item2>& items)
function(std:vector<item2>&& items)
Run Code Online (Sandbox Code Playgroud)
特别是对于较大的数据容器,很少:
function(std:vector<item2> items)
Run Code Online (Sandbox Code Playgroud)
对于较小的数据,从不使用向量。
这样,您可以控制发生的事情,这就是为什么我们使用C ++来控制一切。
显然,这完全取决于您在做什么。
我是一个自学成才的C ++开发人员。远非专家,尤其是C ++ ...语的人……但学习:)