【问题标题】:Implementing an Assignment Operator实现赋值运算符
【发布时间】:2021-11-02 08:03:00
【问题描述】:

我正在尝试编写一个重载的operator= 以将对象studentA 的内容复制分配给studentB。编译后,它只是崩溃并像往常一样“停止工作”。

#include <cstdlib>
#include <iostream>

using namespace std;

class STUDENT {
    public:
        string ID;
        string name;
        unsigned int birthyear;
        STUDENT(string x, string y, unsigned int z) {
            ID = x;
            name = y;
            birthyear = z;
        };
        STUDENT operator = (STUDENT const &obj) {
            STUDENT *res;
                *res = obj;
            return *res; 
        }
        void print() {
            cout << ID << " " << name << " " << birthyear;
        } 
};

int main() {
    STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
    STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
    studentB = studentA;
    studentB.print(); 
    return 0;
}

我认为指针*res 存在一些问题,但我真的不知道它们是什么。我希望你能帮助我。

【问题讨论】:

  • STUDENT *res; 你认为这个指针指向哪里?而且你为什么还要在这里有一个指针?
  • 我们可以通过将一个对象的地址传递给另一个对象来复制成员的值吗?这是这里发生的事情吗?请问有人能解释一下吗。

标签: c++


【解决方案1】:

这里的STUDENT *res; 目前没有指向任何地方,所以你不能给它赋值。
这里不需要STUDENT *res;
你可以return obj;
或者如果您希望将obj 分配给另一个指针然后返回它,您可以这样做

STUDENT operator=(STUDENT const &obj)
    {
        const STUDENT *res;
        res = &obj;  
        //here the pointer res points to the same address as the obj, thus they are pointing to same object.
        return *res;
    }

【讨论】:

    【解决方案2】:

    在您的情况下,您不需要实现自己的copy assignment operator=,因为std::string(unsigned) int 类型都有自己的内置复制运算符。换句话说,他们知道如何安全地复制自己的资源。

    正如@Remy Lebeau 已经建议的那样,最好的选择是使用默认值:

    class_name &amp; class_name :: operator= ( const class_name &amp; ) = default;

    即使您使用标准模板库 containers 中的容器作为成员变量,

    class STUDENT {
       public:
           string ID;
           string name;
           unsigned int birthyear;
           vector v; /*for example std::vector*/
    };
    

    同样,您不必担心复制、移动或管理班级的记忆。他们处理自己的资源!

    容器管理为其分配的存储空间 元素并提供成员函数来直接访问它们 或通过迭代器(属性类似于指针的对象)。

    当您在类中引入指针时,您应该开始担心复制语义,因为这些指针负责管理它们指向的资源!

    class STUDENT {
       public:
           string ID;
           string name;
           unsigned int birthyear;
           float * p; /* this can introduce bug if not handled properly */
    };
    

    您可以阅读有关先前问题的更多信息: herehere

    【讨论】:

      【解决方案3】:

      您的operator= 实施完全错误。当您取消引用并分配给它时,您的 res 指针没有指向任何有意义的地方。这就是你的代码崩溃的原因。

      您需要自己将各个成员从obj 复制到*this,类似于在构造函数中这样做,例如:

      #include <iostream>
      
      using namespace std;
      
      class STUDENT {
         public:
             string ID;
             string name;
             unsigned int birthyear;
      
             STUDENT(string x, string y, unsigned int z) {
                 ID = x;
                 name = y;
                 birthyear = z;
             }
      
             STUDENT& operator=(STUDENT const &obj) {
                 ID = obj.ID;
                 name = obj.name;
                 birthyear = obj.birthyear;
                 return *this; 
             }
      
             void print() const {
                 cout << ID << " " << name << " " << birthyear;
             } 
      };
      
      int main() {
         STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
         STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
         studentB = studentA;
         studentB.print(); 
         return 0;
      }
      

      话虽如此,您使用的是编译器已经知道如何复制的类型,因此您应该让编译器为您生成合适的复制赋值运算符,例如:

      #include <iostream>
      
      using namespace std;
      
      class STUDENT {
         public:
             string ID;
             string name;
             unsigned int birthyear;
      
             STUDENT(string x, string y, unsigned int z) {
                 ID = x;
                 name = y;
                 birthyear = z;
             }
      
             //STUDENT& operator=(STUDENT const &) = default;
      
             void print() const {
                 cout << ID << " " << name << " " << birthyear;
             } 
      };
      
      int main() {
         STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
         STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
         studentB = studentA; // <-- automatically does the "right thing" for you!
         studentB.print(); 
         return 0;
      }
      

      【讨论】:

      • 非常感谢,先生!多亏了你的详细建议,我才勉强完成了我的作业^^!非常感谢再次!!!
      猜你喜欢
      • 2015-08-23
      • 1970-01-01
      • 2011-05-23
      • 2011-08-02
      • 2019-10-06
      • 2011-11-16
      • 2013-11-30
      • 2015-10-02
      • 1970-01-01
      相关资源
      最近更新 更多