构造函数被调用的次数以及地址相同的原因

How many times the constructors are invoked and why the addresses are same

本文关键字:地址 调用 构造函数      更新时间:2023-10-16

源代码:

#include <iostream>
#include <string>
using namespace std;
int counts = 0;
class A {
  public:
    A() {
      cout << ">> A(" << ++counts << ") constructor" << endl;
    }
    A(const A& a) {
      cout << ">> A(" << ++counts << ") copy constructor" << endl;
    }
    A& operator=(const A& a) {
      cout << ">> A(" << ++counts << ") = constructor" << endl;
      return *this;
    }
};
A get_A()
{
  A a1;
  cout << "address of a1 = " << &a1 << endl;
  return a1;
}
void test_1()
{
  A a2 = get_A();
  cout << "address of a2 = " << &a2 << endl;
}
int main()
{
  test_1();
  return 0;
}

输出:

>> A(1) constructor
address of a1 = 0x7fff5296daf8
address of a2 = 0x7fff5296daf8

我的问题:

1.为什么只有一个构造函数被调用?不应该调用赋值构造函数吗

2.为什么a1和a2的地址相同

返回值优化(RVO)是一种编译器优化,它可以消除将在get_a中创建的临时对象复制到test_1中的情况。这就是为什么两个对象都有相同的地址——它们实际上是完全相同的对象。您的编译器正在消除多余的构造和复制,而只是在适当的位置构造结果。

  1. 因为复制省略
  2. 因为复制省略

编译器不使用get_A()的返回值来复制构造a2,而是直接在调用站点分配返回值。

如果在编译器中关闭副本省略(GCC和Clang中的-fno-elide-constructors),您可以看到预期的行为。