为什么这个程序的结果是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 )
{
}
这是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 )
{
}