制作复制构造函数

时间:2012-07-28 15:49:33

标签: c++ oop reference constructor copy-constructor

我对复制构造函数有疑问。我在互联网上看到这些例子。 第一个说没有复制构造函数,如果你在student2上改变某些东西,同样的字段改变也在student1上。但是在第二个例子中,student2上的更改不会因为复制构造函数而影响student1。我不明白这是怎么发生的,实际上复制构造函数在这里做了什么? (抱歉英文不好) (感谢所有答案:))

class MITStudent {
public:
    int studentID;
    char *name;
    MITStudent() {
        studentID = 0;
        name = "";
}

};
   int main() {
      MITStudent student1;
      student1.studentID = 98;
      char n[] = "foo";
      student1.name = n;
      MITStudent student2 = student1;
      student2.name[0] = 'b';
      cout << student1.name; // boo
 }

第二个

class MITStudent {
public:
    int studentID;
    char *name;
    MITStudent() {
        studentID = 0;
        name = "";
    }

    MITStudent(MITStudent &o) {
        name = my_strdup(o.name);
        studentID = o.studentID;
    }

};
int main() {
   MITStudent student1;
   student1.studentID = 98;
   char n[] = "foo";
   student1.name = n;
   MITStudent student2 = student1;
   student2.name[0] = 'b';
   cout << student1.name; // foo

}

5 个答案:

答案 0 :(得分:2)

如果您未指定自己的默认复制构造函数,则会自动生成 他们只是按价值将所有班级成员复制到新班级。

当您将指针作为班级成员时,通常会出现问题 默认的复制构造函数只会复制指针所占据的地址 这意味着原始类和复制类现在都指向同一个对象。

这正是您的示例中使用char*“字符串”...

所发生的情况

BTW,作为一个拇指规则..如果你有一个指针作为成员的类,创建一个自定义复制构造函数。

答案 1 :(得分:0)

如果您不创建复制构造函数,则会自动为您生成复制构造函数。自动生成的复制构造函数只会将指针复制到名称而不是名称本身。通过创建自己的构造函数,您可以手动复制整个名称,而不仅仅是指针。

在实际代码中,您可能希望使用类似std :: string而不是char *的东西。这样,自动生成的复制构造函数将执行您想要的操作,您无需编写自己的。

答案 2 :(得分:0)

如果没有MITStudent(MITStudent &o),则只是复制所有字段的值。因此,如果存在指针字段,则两个字段将包含相同的地址。

答案 3 :(得分:0)

在第一个示例中,复制构造函数由编译器隐式创建。

它基本上是这样的:

MITStudent(const MITStudent &o) {
    name = o.name;
    studentID = o.studentID;
}

它只复制指针name

在第二个示例中,显式创建了复制构造函数,并复制name指向的数据。这样,name中的student2指向复制的数据。

答案 4 :(得分:0)

在典型情况下,使用默认的复制构造函数,情况将在picture!的左侧给出。实现了复制构造函数以避免这种情况,并且具有右侧给出的场景。

但是,通常这会发生在指针成员身上。所以,尽量避免使用它们。只有你使用它们 1.只能在构造函数之后的阶段创建成员 2.想要销毁一个成员并重新创建它 3.想让会员比对象活得更久。

在您的情况下,看起来您不属于上述任何一种情况。在这种情况下,您可以安全地使用漂亮的字符串对象,而不必担心任何悬空指针。