【问题标题】:Copy constructor or assignment operator? What am I missing?复制构造函数还是赋值运算符?我错过了什么?
【发布时间】:2014-03-04 04:55:51
【问题描述】:

我正在尝试实现一个复制构造函数和一个重载的赋值构造函数。 我有一个 Employee 类,它有三个数据成员。 1-姓名 2-职称 3-薪水。

Employee::Employee(const Employee &emp)
{
    name = emp.name;
    title = emp.title;
    salary = emp.salary;
    cout << "\nOverloaded copy constructor called\n";
}
Employee Employee::operator = (const Employee &emp) //Overloading the assignment operator.
{
    name = emp.name;
    title = emp.title;
    salary = emp.salary;
    cout << "\nOverloaded assignment operator called\n";
    return emp;         //Or return *this.
}  

以下是我不明白的地方:
1-我还没有找到“this”指针。我的重载赋值运算符应该返回 *this 还是 emp 对象。因为在我看来,参数中的那个对象是赋值时的右手对象。那么我不应该用 *this 返回左手对象吗(如果 *this 会这样做)?
2-在主函数中,我尝试先调用赋值运算符,然后调用复制构造函数。所以我期待我会一个接一个地看到我在其中包含的 cout 语句,但是,这是我的输出:

调用的重载复制构造函数
重载赋值运算符称为
调用了重载的复制构造函数
称为

的重载复制构造函数

为什么会这样?

3-我必须用 const 传递对象吗?我正在学习的书没有。

主要是我写的

Employee x;
x = another;
Employee y = x;

“another”只是我之前在代码中初始化的一个(命名不佳的)Employee 对象。
所以不应该是第一个作业输出
“调用了重载赋值运算符”和第二个赋值(根据我的理解,这不是赋值而是副本)输出“调用了重载的复制构造函数”

【问题讨论】:

  • 对于数字 2 和 3 - 向我们展示与之相关的代码。

标签: c++ this copy-constructor assignment-operator


【解决方案1】:

赋值运算符通常实现为

Employee& Employee::operator = (const Employee &emp)
{
    name = emp.name;
    title = emp.title;
    salary = emp.salary;
    cout << "\nOverloaded assignment operator called\n";
    return *this;      
}

请注意返回类型的差异作为参考。您可能会发现这个问题/答案很有用 Why must the copy assignment operator return a reference/const reference? 。如果没有看到您在 main() 函数中引用的代码,我们只会猜测您的代码中发生了什么。

【讨论】:

    【解决方案2】:

    1- 我没有找到“this”指针。如果我超载 赋值运算符返回 *this 或 emp 对象。因为看起来 对我来说,参数中的那个对象是右手对象 那作业。所以我不应该用 *this(如果 *this 会这样做)?

    你应该返回*this

    还请注意,首先您应该检查自分配并返回参考:

    Employee& Employee::operator = (const Employee &emp) //Overloading the assignment operator.
    {
        if ( this != &emp)
        {
            name = emp.name;
            title = emp.title;
            salary = emp.salary;
        }
        cout << "\nOverloaded assignment operator called\n";
        return *this;
    } 
    

    Here you can find how to write assignment operator.

    2- 在主函数中,我尝试调用调用赋值 首先是运算符,然后是复制构造函数。所以我期待 我将看到我在其中包含的 cout 语句 不过其他的

    请从main() 插入此代码,以便我们告诉您更多信息。

    【讨论】:

    • 我在这里的其他问题中看到过这个 if 语句,但我不明白它的必要性。自我分配是什么意思?
    • 员工e; e=e;这是明确的,因此看起来不太可能,但是当您在算法和结构中处理对象时,您可能会错误地执行此类操作。
    • 我改变了我的赋值运算符。但是在 if 语句中出现错误(关于 != 的内容与操作数不匹配),因此我将 if 语句更改为 if(this != &emp) 并返回 *this。但是我现在的输出是重载复制构造函数,称为重载赋值运算符,重载复制构造函数称为
    • 我主要写的是Employee x; x = 另一个;员工 y = x; “另一个”只是我之前在代码中初始化的一个(名称不佳的)Employee 对象。所以不应该第一个赋值输出“调用重载赋值运算符”和第二个赋值(根据我的理解,这不是赋值而是副本)输出“调用重载的复制构造函数”
    • 你是如何创建和初始化并传递给这个地方的“另一个”对象的?可能为此对象调用了第一个复制构造函数
    【解决方案3】:

    已编辑:让我们复制构造函数为您做所有事情

    Employee::Employee(const Employee &emp)
    {
       if(this != &emp)
       {
           name = emp.name;
           title = emp.title;
           salary = emp.salary;
       }
    
      cout << "\nOverloaded copy constructor called\n";
    }
    Employee Employee::operator = (const Employee &emp) //Overloading the assignment   .
    {       
       return emp;    //Having common assignment operations similar to copy constructor
    }  
    

    【讨论】:

    • 您正在返回对局部变量的引用,这很糟糕,因为 temp 将被破坏并使引用无效。您的代码也不要修改 this 也不要返回 *this (这是 operator= 的默认行为)
    【解决方案4】:
    1. 重载的赋值运算符应该返回 *this 指针。您可以实现一个私有方法,该方法将复制类成员并从复制构造函数/赋值运算符中调用它,这将减少重复代码。

      void Employee::copy(const A& rhs) throw() 
      {
        name = rhs.name;
        title = rhs.title;
        salary = rhs.salary;
      }
      
      Employee::Employee(const Employee& rhs)
      {
        copy(rhs);
        //  cout << "copy constructor" << endl;
      }
      
      Employee& operator=(const Employee& rhs)
      {
        copy(rhs);
        //  cout << "assignment operator" << endl;
        return *this;
      }
      
    2. 您的赋值运算符实现确实按值返回 Employee 对象(它应该是通过引用),因此临时对象是通过调用复制 c-tor 创建的效果。

      Overloaded copy constructor called // don't know where this printout comes from as I don't know what happens with 'another' object
      Overloaded assignment operator called // x = another; call
      Overloaded copy constructor called // the temporary object created by assignment operator's return statement (*this should be returned by reference not by value)
      Overloaded copy constructor called // Employee y = x; cal
      
    3. 当您不打算修改输入参数时,应始终将其作为 const 传递。我想你问关于在赋值运算符等中将 Employee 对象作为 const 引用传递? - 它们应该是 const 引用

    更多关于赋值运算符中的异常安全和自赋值处理: GotW 59GotW 23

    【讨论】:

      猜你喜欢
      • 2015-01-11
      • 1970-01-01
      • 2012-03-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      相关资源
      最近更新 更多