为什么在这种情况下调用空构造函数?

时间:2021-05-17 00:31:09

标签: c++

我是 C++ 的初学者,我很难从练习本上理解这个程序,特别是为什么空构造函数总共被调用了 6 次:

#include <iostream>

class Allo{
 public:
   Allo(int x_=0)
    : x(x_)
   {
     std::cout << "A" << x << " ";
   }
   Allo(const Allo& autre)
    : x(autre.x)
   {
     std::cout << "B" << x << " ";
   }
   ~Allo() {
     std::cout << "C" << x << " ";
   }

   int x;
};


void f1(Allo a1, Allo* a2, Allo* a3){
   a1.x++;
   a2->x -= 1;
   a3+=1;
   (a3->x)+=2000;
}

int main(){
   Allo tab[3];
   Allo a(20);
   Allo* b = new Allo(5);
   Allo* c = tab + 1;
   f1(a, b, c);
   std::cout << std::endl << "-------" << std::endl;
   Allo* t = new Allo[4];
   t[2] = Allo(9);
   std::cout << std::endl;
   return 0;
}

输出是:

A0 A0 A0 A20 A5 B20 C21 
-------
A0 A0 A0 A0 A9 C9 
C20 C2000 C0 C0

显示最后调用了 4 次空构造函数。这是为什么? t[2] = Allo(9); 不应该是调用构造函数的最后一行吗?

1 个答案:

答案 0 :(得分:2)

前言:A 是常规构造函数,B 是复制构造函数,C 是析构函数(不是构造函数)。

让我分解每一行:

Allo tab[3];

3 个用构造函数 A 构造的对象,初始化为 x = 0。这些是堆栈分配的。

Allo a(20);

1 个用 A 构造的对象,x = 20。这是堆栈分配的。

Allo* b = new Allo(5);

1 个用 A 构造的对象,x = 5。这是堆分配的。

Allo* c = tab + 1;

构造了 0 个对象,这与 Allo* c = &tab[1] 相同。

f1(a, b, c);

1 个用 B 复制构造的对象,x = 20(因为第一个参数是按值传递的)。当 x = 21 时,这个对象会在 f1 的末尾被销毁(用 C)。

std::cout << std::endl << "-------" << std::endl;
Allo* t = new Allo[4];

4 个用 A 构造的对象,x = 0。这些是堆分配的。

   t[2] = Allo(9);
   std::cout << std::endl;
   return 0;
}

1 个用 A 构造的对象,x = 9。这是堆栈分配的。

5 个对象(此函数中所有堆栈分配的对象)在末尾以与构造相反的顺序用 C 析构。