0

I am writing a simple code, in which I have a list of objects of class Person. The Person class

class Person
{
    private:
        std::string name;
        std::string surname;
        int year;
        
    public:
        Person(const std::string& personName,
               const std::string& personSurname, 
               const int& personYear ):
               name(personName), surname(personSurname), year(personYear) {}
               
        Person(const Person& p): name(p.name), surname(p.surname), year(p.year) { }
        
        Person(Person &&p) noexcept: name(std::move(p.name)), surname(std::move(p.surname)), year(std::move(p.year)) { }
        
        int getYear()
        {
            return year;
        }
        
        void print()
        {
            std::cout << name << " " << surname << " " << year << std::endl;
        }
};

in which, the move constructor is

        Person(Person &&p) noexcept: name(std::move(p.name)), surname(std::move(p.surname)), year(std::move(p.year)) { }

I also have the node structure

struct node
{
    Person data;
    node *next;
    inline node(const std::string& personName,
                const std::string& personSurname, 
                const int& personYear): data(personName, personSurname, personYear), next(nullptr) { }
    inline node(const Person& personToInsert): data(personToInsert), next(nullptr) {} 
    inline node(Person &&personToInsert): data(std::move(personToInsert)), next(nullptr) {}
};

whose move constructor is

    inline node(Person &&personToInsert): data(std::move(personToInsert)), next(nullptr) {}

and finally I have the list class

class list
{
    private:
    node *head;
    
    public:
    list();
    ~list();
    void insert(const std::string&, const std::string&, const int& );
    void insert(const Person& );
    void insert(Person &&);
    void print();
};

whose move constructor is

void list::insert(Person &&personToInsert) {
    node *new_node = new node(std::move(personToInsert));
    if(head == nullptr || (head->data).getYear() >= (new_node->data).getYear())
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;
        while(current->next != nullptr && (current->next->data).getYear() < (new_node->data).getYear())
        {
            current = current->next;
        }
        new_node->next = current->next;
        current->next = new_node;
    } 
}

My question is: inside the move constructors, is the use of std::move correct? Particularly in the first line of code of list::insert

4

1 回答 1

1

inside the move constructors, is the use of std::move correct?

Yes.

Particularly in the first line of code of list::insert

This is correct, too.

Note, however, that there are two minor things I would like to point out. First, there is no need to manually define the move constructor for Person. If your class doesn't do manual resource handling (memory, IO handles etc.), just rely on the special member functions that the compiler generates for you. In this case, I would just remove Person's move and copy constructor.

Second,

inline node(Person &&personToInsert)

is not a move constructor. It's an ordinary constructor that happens to take an rvalue-reference parameter. Move constructors are for constructing an object from an rvalue reference of their own type.

Third,

void list::insert(Person &&personToInsert)

is not a constructor at all - it's an ordinary member function that happens to accept an rvalue parameter.

于 2021-05-27T08:30:40.430 回答