我对复制构造函数和赋值运算符有疑问。我知道在定义构造函数时,默认的构造函数不会由编译器合成。我的疑问是仅定义复制构造函数是否可以。我不会说,因为如果定义了副本构造函数,那么默认的构造函数不会被合成,因此我无法初始化对象,因为我需要该类的对象,而我没有。我不知道这是对的。我的第二个疑问是关于包含指针的类的类似值的实现。到目前为止,我所看到的每个代码在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);这也正确吗?
答案 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
而不是指向一个指针的指针将消除定义任何特殊成员函数的需要。