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

时间:2012-05-23 21:13:30

标签: c++ class constructor

星期六我参加了考试,我查看过去的论文,并且根据C ++代码我遇到过问题:

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

第5行声明的目的是什么?一般来说,实施这种性质的声明应该提供哪些功能?在第5行写下声明实现所需的代码,如同提供的信息一样,它将出现在Car.cpp文件中。

5 个答案:

答案 0 :(得分:9)

让我们来看看。

从名称可以看出,这是一个构造函数。因为它需要一个参数引用相同类型的对象,所以它是复制构造函数(C ++命名法)。

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

为什么要实现自己的:

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

我已经修改了你的课程以便更好地解释。你的班级现在管理记忆。它为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将分配新内存来保存车牌,因此不能进行双重删除。

我更改了代码以证明这一点,但你仍然必须自己将逻辑放在那里。

答案 1 :(得分:8)

它是一个复制构造函数,它的目的是制作作为参数给出的对象的精确副本。

我会留给你决定如何最好地做到这一点。

答案 2 :(得分:2)

这是一个复制构造函数声明。它需要引用常量Car,这意味着你可以读取传入的值,但不能(没有狡猾的强制转换)写入它。这只是通过复制原始文件来创建新对象的规范方法。您可能希望在实施过程中执行strdup

答案 3 :(得分:0)

声明称为复制构造函数。通常,复制构造函数用于为类构造给定实例的新实例。

在签名中:

Car(const Car &)

“const”表示无法在方法中修改传递的实例。 “&安培;”意味着实例通过引用传递给方法。在没有“&”的情况下传入一个类的实例(按值传递)将使用复制构造函数创建类的新实例。在声明复制构造函数的情况下,通过值传递不仅会自我失败,而且会导致复制构造函数被递归调用,直到遇到堆栈溢出。

进入cpp文件的代码应该是传入的实例的可接受副本。可以根据用户场景采用合理的方式。

答案 4 :(得分:-3)

我假设你的意思是第5行,然后是

Car(const Car &);

是一个构造函数,其唯一参数是对另一个Car对象的引用。它标记为const表示构造函数不应该修改给定的汽车。由于它是一个引用,你需要检查以确保你没有以某种方式引用正在构造的同一个对象:

if (this==car){
  return;
}

或类似的东西。