有这样的代码:
#include <iostream>
class A {
public:
int a;
A() : a(0) {
std::cout << "Default constructor" << " " << this << std::endl;
}
A(int a_) : a(a_) {
std::cout << "Constructor with param " << a_ << " " << this << std::endl;
}
A(const A& b) {
a = b.a;
std::cout << "Copy constructor " << b.a << " to " << a << " " << &b << " -> " << this << std::endl;
}
A& operator=(const A& b) {
a=b.a;
std::cout << "Assignment operator " << b.a << " to " << a << " " << &b << " -> " << this << std::endl;
}
~A() {
std::cout << "Destructor for " << a << " " << this << std::endl;
}
void show(){
std::cout << "This is: " << this << std::endl;
}
};
A fun(){
A temp(3);
temp.show();
return temp;
}
int main() {
{
A ob = fun();
ob.show();
}
return 0;
}
结果:
Constructor with param 3 0xbfee79dc
This is: 0xbfee79dc
This is: 0xbfee79dc
Destructor for 3 0xbfee79dc
对象ob由函数fun()初始化。为什么没有在那里调用复制构造函数?我认为当函数按值返回时,将调用复制构造函数或赋值运算符。似乎函数fun()中构造的对象在执行函数后不会被销毁。在这种情况下,如何强制复制构造函数来调用?
这是由g ++编译的。
答案 0 :(得分:4)
答案 1 :(得分:3)
这称为命名返回值优化和复制省略,基本上意味着编译器已经发现可以通过小心地放置临时和对象在同一个内存位置。
默认情况下,该段代码中会有三个对象,temp
内的fun
,主要内部的返回值和ob
,以及多达两个副本,但要小心将temp
放在与fun
内返回的对象相同的内存位置,并将ob
放在同一内存地址中,可以优化掉两个副本。
我用两张图片写了关于这两个优化的文章来解释这里发生了什么: