【发布时间】:2015-02-26 02:27:01
【问题描述】:
我听说由于引入了移动语义,您应该始终更喜欢 C++11 中的“按值传递”。我想看看炒作的全部内容并构建了一个测试用例。首先是我的班级:
struct MyClass {
MyClass() { }
MyClass(const MyClass&) { std::cout << "Copy construct" << std::endl; }
MyClass(MyClass&&) { std::cout << "Move construct" << std::endl; }
~MyClass() { }
};
以及测试工具:
class Test
{
public:
void pass_by_lvalue_ref(const MyClass& myClass)
{
_MyClass.push_back(myClass);
}
void pass_by_rvalue_ref(MyClass&& myClass)
{
_MyClass.push_back(std::move(myClass));
}
void pass_by_value(MyClass myClass)
{
_MyClass.push_back(std::move(myClass));
}
private:
std::vector<MyClass> _MyClass;
};
据推测,pass_by_value 应该优于pass_by_lvalue_ref 和pass_by_rvalue_ref(一起,而不是单独)。
int main()
{
MyClass myClass;
Test Test;
std::cout << "--lvalue_ref--\n";
Test.pass_by_lvalue_ref(myClass);
std::cout << "--rvalue_ref--\n";
Test.pass_by_rvalue_ref(MyClass{});
std::cout << "--value - lvalue--\n";
Test.pass_by_value(myClass);
std::cout << "--value - rvalue--\n";
Test.pass_by_value(MyClass{});
}
这是我在 GCC 4.9.2 上使用-O2 的输出:
--lvalue_ref--
Copy construct
--rvalue_ref--
Move construct
Copy construct
--value - lvalue--
Copy construct
Move construct
Copy construct
Copy construct
--value - rvalue--
Move construct
如您所见,非pass_by_value 函数总共需要 2 个复制构造和 1 个移动构造。 pass_by_value 函数总共需要 3 个复制构造和 2 个移动构造。看来,果然还是要复制对象,那为什么大家都说按值传递呢?
【问题讨论】:
-
测试工具坏了。您的一些
push_backs 会触发重新分配,而另一些则不会。按值传递并不是一对重载的性能提升。这是一个可维护性的增益。 -
作为 T.C.说,确保您的
vector足够大以防止重新分配 - coliru.stacked-crooked.com/a/e424a3073bdc727c 另外,这是您的 another version of your example 导致重新分配,但在发生这种情况时避免复制构造,注意区别吗? (我做了MyClass的移动构造函数noexcept) -
_Typename作为变量的名称是一个非常可怕的命名约定...... -
@MattMcNabb 更不用说它使用了一个保留的标识符......
标签: c++ c++11 move-semantics pass-by-value