Copy-конструктор, оператор присваивания, новый - PullRequest
0 голосов
/ 08 июля 2019

У меня есть некоторые сомнения по поводу конструктора копирования и оператора присваивания.Я знаю, что когда я определяю конструктор, конструктор по умолчанию не синтезируется компилятором.Я сомневаюсь, что можно определить только конструктор копирования.Я бы сказал нет, поскольку, если я определю конструктор копирования, конструктор по умолчанию не синтезируется, поэтому я не могу инициализировать объекты, потому что мне нужен объект этого класса, которого у меня нет.Я не знаю, правильно ли это.Мое второе сомнение связано со значением-реализацией класса, содержащего указатель.Каждый код, который я видел до сих пор, использует оператор 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;
    }
 }

В документе говорится, что конструктор должен быть реализован.Что насчет конструктора?Как я могу создать экземпляр класса, не имея конструктора (который не является конструктором копирования), в этом случае?Более того, я не понимаю, почему он использует new в конструкторе копирования и в операторе присваивания.Я бы сделал, например, в теле оператора присваивания, * books = * (other.books);это тоже правильно?

1 Ответ

0 голосов
/ 08 июля 2019

Извлечение Правило трех , которое гласит, что вы, как правило, должны определять конструктор копирования, оператор присваивания и деструктор, если таковые необходимы.Если у вас есть причина для определения одного из них, у вас почти наверняка есть причина для определения других.Вы управляете динамической памятью, что означает, что вы, вероятно, должны инициализировать это в конструкторе.

Ваши операторы копирования и присваивания должны сделать new std::vector<Book> (*other.books);, потому что если они копируют только указатели, такие как books = other.books;, вы закончитес двумя Students, разделяющими один и тот же Books, который (обычно) является рецептом катастрофы.

(Примечание: вы можете сэкономить головную боль с помощью идиома копирования и обмена .)

Наконец, убедитесь, что деструктор deletes выделил всю память, выделенную вам.,И, как заметил @Ted Lyngmo, в этом конкретном случае использование простого std::vector вместо указателя на один избавит от необходимости определять любую из специальных функций-членов.

...