目录
1.copy elision说明
Copy elision (或Copy omission)是一项编译器优化技术,用于避免不必要的对象拷贝。现如今基本上所有的编译器都使用它。
参考下面的程序。
#include <iostream>
class B
{
public:
B(const char* str = "\0") //默认构造函数
{
std::cout << "Constructor called" << std::endl;
}
B(const B &b) //拷贝构造函数
{
std::cout << "Copy constructor called" << std::endl;
}
};
int main()
{
B ob = "copy me";
return 0;
}
输出结果:
Constructor called
2.优化分析
上面例子,为何没有调用拷贝构造函数?
按照正常的思维, 当一个对象 “ob”被创建时,会先调用一个带参数的构造函数,将"copy me"转换为一个临时对象,然后调用拷贝构造函数,将此临时对象拷贝给对象"ob". 这样的话,下面的这个表达式
B ob = "copy me";
可以被编译器替换为:
B ob = B("copy me");
然而,绝大多数的编译器都会避免掉这种开销。
现代的C++编译器会将下面的这个表达式
B ob = "copy me"; //拷贝初始化
替换为:
B ob("copy me"); //直接初始化
因此,省略掉了拷贝构造这一步。
3.如何关闭优化
当然,如果我们不想让编译器忽略掉拷贝构造函数,可以disable the copy elision, 方法就是在使用g++编译时,带上“-fno-elide-constructors”这个选项。
参考下面例子:
root@shltsh:~$ g++ copy_elision.cpp -fno-elide-constructors
root@shltsh:~$ ./a.out
Constructor called
Copy constructor called
如上所述,如果使用了这个编译选项,则先调用默认构造函数创建一个临时对象,然后调用拷贝构造函数将临时对象拷贝给ob。