我对复制构造函数有疑问。我在互联网上看到这些例子。 第一个说没有复制构造函数,如果你在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
}
答案 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.想让会员比对象活得更久。
在您的情况下,看起来您不属于上述任何一种情况。在这种情况下,您可以安全地使用漂亮的字符串对象,而不必担心任何悬空指针。