【问题标题】:Why the result of this program is 3 "born"?And 4 dead为什么这个程序的结果是3个“出生”?而4个死了
【发布时间】:2020-05-31 14:10:57
【问题描述】:

这是 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个“出生”?4个死了? 初始化对象数组'arr'的过程是什么?

【问题讨论】:

  • result.age = (*this).age + a.age; --> result.age = age + a.age;。你只是用显式的this 取消引用来混淆你的代码(在任何情况下,this-&gt;age 会更好)。(*this).age 只是 odd
  • 默认的复制构造函数不提供“我是复制而生的。\n”反馈。
  • 这里编译:https://ideone.com/nHKZ30

标签: c++ class destructor copy-constructor construct


【解决方案1】:

失踪的出生人是克隆人!注意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 毫无意义。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      在数组的这个声明中

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

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

      在本次通话中

      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] 通过调用隐式定义的复制构造函数的值传递给函数。这样就创建了该类的第三个对象。

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

          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 )
      {
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多