C++ 复制构造函数
我有一个关于复制构造函数的问题。我在网上看到了这些例子。 第一种说法是,如果在student2上更改了某些内容,那么在student1上也会更改相同的字段。但在第二个示例中,student2上的更改不会影响student1,因为复制构造函数。我不明白这是怎么发生的,复制构造函数在这里到底做了什么?(抱歉英语不好) (谢谢你的回答:))C++ 复制构造函数,c++,oop,reference,constructor,copy-constructor,C++,Oop,Reference,Constructor,Copy Constructor,我有一个关于复制构造函数的问题。我在网上看到了这些例子。 第一种说法是,如果在student2上更改了某些内容,那么在student1上也会更改相同的字段。但在第二个示例中,student2上的更改不会影响student1,因为复制构造函数。我不明白这是怎么发生的,复制构造函数在这里到底做了什么?(抱歉英语不好) (谢谢你的回答:)) 班级学生{ 公众: 国际学生; 字符*名称; 学生({ studentID=0; name=“”; } }; int main(){ 麻省理工学院学生1; stu
班级学生{
公众:
国际学生;
字符*名称;
学生({
studentID=0;
name=“”;
}
};
int main(){
麻省理工学院学生1;
student1.studentID=98;
字符n[]=“foo”;
student1.name=n;
学生2=学生1;
学生2.姓名[0]=“b”;
cout如果您不创建复制构造函数,则会自动为您生成一个复制构造函数。自动生成的复制构造函数将只复制指向名称的指针,而不是名称本身。通过创建自己的构造函数,您可以手动复制整个名称,而不仅仅是指针
在实际代码中,您可能希望使用std::string之类的内容,而不是char*。这样,自动生成的复制构造函数将执行您想要的操作,并且您无需编写自己的复制构造函数。如果您不指定自己的复制构造函数,则会自动生成默认的复制构造函数。
他们只是将所有类的成员按值复制到新类中
当指针作为类成员时,问题通常会出现。
默认的复制构造函数将只复制指针持有的地址。
这意味着原始类和复制类现在都指向同一个对象
这正是您的示例中使用char*
“string”时发生的情况
顺便说一句,作为一条经验法则。如果您有一个以指针为成员的类,请创建一个自定义副本构造函数。如果没有MITStudent(MITStudent&o)
它只是复制所有字段的值。因此,如果存在指针字段,则两个字段将包含相同的地址。在第一个示例中,复制构造函数由编译器隐式创建
基本上是这样的:
MITStudent(const MITStudent &o) {
name = o.name;
studentID = o.studentID;
}
它只复制指针名称
在第二个示例中,显式创建复制构造函数并复制name
指向的数据。这样,student2
中的name
指向复制的数据。在典型情况下,使用默认的复制构造函数,情况将如s的实现是为了避免这种情况,并具有右侧给出的场景
但是,指针成员通常会发生这种情况。因此,请尽量避免使用它们。仅当您需要时才使用它们
1.只能在比构造函数更晚的阶段后才能创建成员
2.要销毁一个成员并重新创建它吗
3.希望使成员比对象寿命长
在您的情况下,看起来您不在上述任何情况下。在这种情况下,您可以安全地使用nice string对象,并且不必担心任何悬空指针。但是有两个构造函数。@user1559792:是的,您的示例中有一个默认构造函数和一个副本构造函数。const
。与问题无关。我建议使用std::string
。我不太确定这是一个很好的经验法则,因为在使用指针和需要自定义副本构造函数的类中,更好的规则几乎总是去掉这些指针,因为标准库中有适合pur的类姿势更好。所以,在剩下的几个地方,指针实际上是有用的(我使用它们的目的就是不拥有可重新分配的引用),不需要自定义复制构造函数。确实,您应该尝试完全避免使用指针,但实际上不能。如果您使用shared_ptr,它会变得非常安全和方便。但是,您仍然需要定义一个复制构造函数,以便用指针定义正确的行为。我不是说您应该尝试避免使用指针r、 我是说,在大多数由于指针而需要编写自定义副本构造函数的地方(例如,因为需要动态数组),这些地方都是不应该使用指针的地方(因为标准库有一个动态数组类,std::vector
).在为指针保留的少数位置(不拥有可重新分配的引用,我们这里讨论的是原始指针),不需要自定义副本构造函数。
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
MITStudent(const MITStudent &o) {
name = o.name;
studentID = o.studentID;
}