0
votes

I have some doubts about copy constructor and assignment operator. I know that when I define a constructor, the default constructor is not synthetized by the compiler. My doubt is if it is ok to define just the copy constructor. I would say no since if I define the copy constructor the default constructor is not synthetized so I cannot initialize objects, because I would need an object of that class, which I don't have. I don't know if this is right. My second doubt is about value-like implementation of a class containing a pointer. Every code I've seen until now use the new operator inside both copy and assignment operator. For instance:

#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;
    }
 }

The document says that a constructor should be implemented. What bout the constructor? How can I instantiate a class without having a constructor(which is not the copy constructor), in this case? Morover, I don't understand why it uses new in the copy constructor and in the assignment operator. I would do for instance, in the assignment operator body, *books = *(other.books); is this also correct?

1
books needs a memory slot for *books = *(other.books); to work. Thus, you need to allocate memory for your vector. Of course the use of a dynamically allocated vector is questionable, but I'm not sure your question is hereAdrien Givry
... but since you have a vector to hold Books - new seems like a bad idea.Ted Lyngmo
Why pointer of vector?Kevin Kouketsu
Do: std::vector<Book> books; and in the copy ctor and copy assignment operator: books = other.books;Ted Lyngmo
change std::vector<Book> * books; to std::vector<Book> books; and you don't need to define any of the special member functions.NathanOliver

1 Answers

0
votes

Check out The Rule of Three, which states that you should typically define a copy constructor, an assignment operator, and a destructor if any are needed. If you have a reason to define one of these, you almost certainly have a reason for defining the others. You are managing dynamic memory, which means you should likely initialize that in the constructor.

Your copy and assignment operators have to do new std::vector<Book> (*other.books); because if they only copy the pointers, like books = other.books;, you will end up with two Students sharing the same Books, which is (usually) a recipe for disaster.

(Side note: you can save some headache with the copy-and-swap idiom.)

Finally, make sure your destructor deletes any memory you allocate. And as @Ted Lyngmo noted, in this specific case, using a plain std::vector instead of a pointer to one will eliminate the need to define any of the special member functions.