复制构造函数,赋值运算符,新的

时间:2019-07-08 19:20:17

标签: c++ copy-constructor assignment-operator

我对复制构造函数和赋值运算符有疑问。我知道在定义构造函数时,默认的构造函数不会由编译器合成。我的疑问是仅定义复制构造函数是否可以。我不会说,因为如果定义了副本构造函数,那么默认的构造函数不会被合成,因此我无法初始化对象,因为我需要该类的对象,而我没有。我不知道这是对的。我的第二个疑问是关于包含指针的类的类似值的实现。到目前为止,我所看到的每个代码在copy和Assign运算符中都使用new运算符。例如:

#include <string>
#include <vector>
#include "book.hh"

class Student
{
    std::string name;
    unsigned int id;
    unsigned int age;
    char gender;
    std::vector<Book> * books;

 /*Copy-constructor*/
    Student (const Student & other)
    {
        name = other.name;
        id = other.id;
        age = other.age;
        gender = other.gender;
        books = new std::vector<Book> (*other.books);
    }

 /*Assignment operator*/
    Student & operator = (const Student & other)
    {
        if (this != &other)
        {
            name = other.name;
            id = other.id;
            age = other.age;
            gender = other.gender;
            delete books;
            books = new std::vector<book> (*other.books);
        }
        return *this;
    }
 }

该文档说应该构造一个构造函数。什么构造函数?在这种情况下,如何在没有构造函数(不是复制构造函数)的情况下实例化类? Morover,我不明白为什么它在复制构造函数和赋值运算符中使用new。例如,我将在赋值运算符主体中执行* books = *(other.books);这也正确吗?

1 个答案:

答案 0 :(得分:0)

签出The Rule of Three,它指出您通常应定义一个复制构造函数,一个赋值运算符和一个析构函数(如果需要)。如果您有理由定义其中之一,则几乎可以肯定地有理由定义其他理由。您正在管理动态内存,这意味着您可能应该在构造函数中对其进行初始化。

您的复制和赋值运算符必须执行new std::vector<Book> (*other.books);,因为如果它们仅复制指针,例如books = other.books;,则最终将有两个Students共享相同的Books ,(通常)是灾难的秘诀。

(旁注:使用copy-and-swap idiom可以省些头痛。)

最后,确保析构函数deletes分配了所有内存。正如@Ted Lyngmo所指出的,在这种特定情况下,使用普通的std::vector而不是指向一个指针的指针将消除定义任何特殊成员函数的需要。