为什么这个程序的结果是3"born"?而且4死了

Why the result of this program is 3 "born"?And 4 dead

这是main.cpp:

int main() {

    Person arr[2] = {
        Person(18,180),
        Person(20,173)
    };
    arr[0]+arr[1];

    return 0;
}  

这是Person.h:

class Person
{
private:
    int age;
    int height;
public:
    Person(int age=20,int height=180);
    ~Person();
    void operator+(Person);
};

这是Person.cpp:



Person::Person(int age,int height) {
    (*this).age = age;
    (*this).height = height;
    cout << "I'm born.\n";
}

Person::~Person() {
    cout << "I'm dead.\n";
}

void Person::operator+(Person a) {
    Person result;
    result.age = (*this).age + a.age;
    result.height = (*this).height + a.height;
    cout << result.age << endl;
    cout << result.height << endl;
}

为什么这个程序的结果是3"born"?而且4死了? 初始化对象数组的过程是怎样的'arr'?

失踪的出生者是克隆人!注意 operator+ 按值获取参数,因此调用复制构造函数(在本例中为默认构造函数)。要查看此内容,请添加

Person::Person(const Person &p) {
    this->age = p.age;
    this->height = p.height;
    cout << "I'm a clone.\n";
}

到你的代码——那么为什么最后死了4个人就很清楚了。一个更好的主意是让您的奇数运算符拥有此签名以避免复制并明确:

void Person::operator+(const Person &a) const;

另外,当你有箭头运算符时,使用 *this 毫无意义。

operator+ 中,加法的第二个参数,即第一个参数,按值传递,因此称为复制构造函数(未重新定义,因此您没有跟踪用它构建的对象)以便构建它,因此在函数调用结束时该对象被破坏(所以这是你的第 4 个 "hidden" 死人)

让我们一起数一数构造函数和析构函数的调用次数。

在这个数组声明中

Person arr[2] = {
    Person(18,180),
    Person(20,173)
};

构造函数被调用两次,因为正在创建 class 的两个对象。这里省略了复制构造函数的调用。

在本次通话中

arr[0]+arr[1];

这里用到了下面的函数

void Person::operator+(Person a) {
    Person result;
    result.age = (*this).age + a.age;
    result.height = (*this).height + a.height;
    cout << result.age << endl;
    cout << result.height << endl;
}

参数 arr[1] 通过调用隐式定义的复制构造函数的值传递给函数。因此创建了 class 的第三个对象。

在该函数中,在此声明中创建了第四个对象

    Person result;

因此创建了四个对象,其中三个使用带参数的构造函数创建,一个使用复制构造函数创建。所以结果也调用了四个析构函数。

运算符的声明和定义至少要像

Person Person::operator +( const Person &a) const {
    return Person( age + a.age, height + a.height );
}

另一方面,最好使构造函数显式化。例如

explicit Person(int age=20,int height=180) : age( age ), height( height )
{
}