c++ - C++类中的奇怪构造函数

标签 c++ class constructor

星期六我有一个考试,我正在浏览过去的试卷,我遇到了根据 C++ 代码编写的问题:

class Car {
     char *LicencePlate;
     int age;
public:
     Car(const Car &); //this declaration
     ~Car();
}

第 5 行声明的目的是什么?一般来说,这种性质的声明的实现应该提供什么功能?根据所提供的信息,在第 5 行编写实现声明所需的代码,因为它将出现在 Car.cpp 文件中。

最佳答案

让我们来看看这个。

顾名思义,这是一个构造函数。因为它采用对同一类型对象的引用作为参数,所以它是一个复制构造函数(C++ 命名法)。

如您所知(或不知道),如果您没有复制构造函数,编译器会为您生成一个。编译器生成的复制构造函数执行浅复制

为什么要实现自己的:

class Car {
     char *LicencePlate;
public:
     Car(char* plate, int size)
     {
        LicencePlate = new char[size];
        strcpy(LicencePlate, plate);
     }
     ~Car()
     {
        delete[] LicencePlate;
     }
};

为了更好地解释,我对您的类(class)进行了一些修改。你的类(class)现在管理内存。它为 LicencePlate 分配内存。这是您没有复制构造函数的情况。假设你这样做:

Car a("abc",3);

编译器生成的复制构造函数被调用:

Car b(a);

但请记住,这只会进行浅拷贝。所以,实际上,a.LicencePlate == b.LicencePlate你能看出这有什么问题吗?

a 超出范围时,将调用析构函数,并删除 a.LicencePlate。但是当 b 超出范围时你会遇到未定义的行为,因为 b 的析构函数将尝试删除相同的内存(记住,两个指针指向相同的内存,因为创建了一个浅拷贝)。

为避免这种情况,您可以定义自己的复制构造函数:

class Car {
     char *LicencePlate;
     int sz;
public:
     Car(char* plate, int size)
     {
        LicencePlate = new char[size+1]();
        strcpy(LicencePlate, plate);
        sz = size;
     }
     Car(const Car& other)
     {
        LicencePlate = new char[other.sz+1]();
        sz = other.sz;
        strcpy(LicencePlate, other.LicencePlate);
     }
     ~Car()
     {
        delete[] LicencePlate;
     }
};

三原则 意味着您应该实现一个赋值运算符(您已经有一个复制构造函数和一个析构函数)。这背后的动机是相同的,只是当您分配而不是初始化时问题会重复:

Car a("abc",3);
Car b;
b = a; //assignment - operator= is called

现在我们安全了。 b复制时会分配新内存存放车牌,所以不会出现双删。

我更改了代码以证明这一点,但您仍然需要自己将逻辑放入其中。

关于c++ - C++类中的奇怪构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10727926/

相关文章:

c++ - 以编程方式打印时,我可以为每个页面指定不同的页面大小吗?

c++ - 在 C++ 的构造函数中初始化一个数组

matlab - 未定义函数 'addListener'

c++ - 派生类错误 'no type named my_data in <base class>'

java - 调用另一个构造函数时有什么方法可以访问 this.toString() 的值吗?

c++ - 性能断言

php - 将 PHP 数组转换为类变量

c++ - 尽管可见,但未设置静态变量

java - 我可以在构造函数中包含什么?

c++ - 数组地址不可见