我在 Linux Ubuntu 中编写的 C++ 应用程序中目睹了一些意外行为。我将构造一个带有参数的对象,然后使用赋值运算符将该对象的副本放入 std::map 中。我写了一个简单的程序来演示这种情况......
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Foo
{
public:
Foo(void) : _x(0)
{
cout << "Default" << endl;
}
Foo(int a) : _x(a)
{
cout << "Param" << endl;
}
Foo(Foo const &foo) :
_x(foo._x)
{
cout << "Copy" << endl;
}
Foo& operator=(Foo const &foo)
{
cout << "Assignment" << endl;
if (this != &foo)
{
_x = foo._x;
}
return *this;
}
int get(void)
{
return _x;
}
private:
int _x;
};
int main(int argc, char *argv [])
{
std::map<int, Foo> foos;
Foo a_foo(10);
foos[100] = a_foo;
return 0;
}
在这里,我只是打印出哪个构造函数/运算符以什么顺序被调用,这样我就可以看到构造和赋值在“main”函数中是如何工作的。
当我在 Windows 中运行它时,我得到了预期的输出......
Param
Default
任务
当我在 Linux 中运行它时,我得到以下输出......
Param
Default
Copy
Copy
任务
为什么会有两个额外的复制构造函数?创建对象这么多次看起来效率很低?
Thanks!
The answer lies in stl_map.h. Its behaviour depends on whether you compile with C++11 support or not. If you do then the STL can take advantage of move semantics to avoid unnecessary copying. VC++ uses the new language features by default but if you use g++ or clang you need to get used to using the -std=c++0x
flag in 4.2 or -std=c++11
in newer versions.
With -std=c++11
使用 g++4.8 设置输出为:
Param
Default
Assignment
Edit:非常感谢您为我澄清,我认为这取决于移动语义的假设是不正确的。我保留这个答案以引导用户这个更好的 https://stackoverflow.com/questions/30694450/spurious-copies-in-c03-libstdc-vs-c11.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)