C++ 复制构造函数

C++ 复制构造函数,c++,oop,reference,constructor,copy-constructor,C++,Oop,Reference,Constructor,Copy Constructor,我有一个关于复制构造函数的问题。我在网上看到了这些例子。 第一种说法是,如果在student2上更改了某些内容,那么在student1上也会更改相同的字段。但在第二个示例中,student2上的更改不会影响student1,因为复制构造函数。我不明白这是怎么发生的,复制构造函数在这里到底做了什么?(抱歉英语不好) (谢谢你的回答:)) 班级学生{ 公众: 国际学生; 字符*名称; 学生({ studentID=0; name=“”; } }; int main(){ 麻省理工学院学生1; stu

我有一个关于复制构造函数的问题。我在网上看到了这些例子。 第一种说法是,如果在student2上更改了某些内容,那么在student1上也会更改相同的字段。但在第二个示例中,student2上的更改不会影响student1,因为复制构造函数。我不明白这是怎么发生的,复制构造函数在这里到底做了什么?(抱歉英语不好) (谢谢你的回答:))

班级学生{
公众:
国际学生;
字符*名称;
学生({
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;
}