Should move semantics be used in constructor chains?

为君一笑 提交于 2019-12-10 22:19:46

问题


Suppose I have the following two classes:

class Person
{
    public:
        Person(string name, string surname)
            : _name(move(name)), _surname(move(surname)) { }
        ...
    private:
        string _name;
        string _surname;
};

class Student : public Person
{
    public:
        Student(string name, string surname, Schedule schedule)
            : Person(move(name), move(surname)), _schedule(move(schedule)) { }
        ...
    private:
        Schedule _schedule;
};

int main()
{
    Student s("Test", "Subject", Schedule(...));
    ...
    return 0;
}

Is that a good usage of move semantics? As you can see there's a layer of 'move-s' in the Student constructor. Is it possible to avoid the move function call overhead without using const references to forward the parameters to the base constructor?

Or perhaps..should I be using const references whenever I need to forward parameters to the base constructor?


回答1:


No. You will only get a performance improvement for types which are of a very large size, which is very rare. Absolutely, when dealing with some type which you don't know in advance is very expensive to move, or immovable, then assume cheap moves.

Your existing code is idiomatic C++11, and a perfect forwarding constructor in this respect is wrong and will hideously break things for one parameter to boot.




回答2:


Consider favoring code readability and simplicity before choosing to optimize. It is quite likely that you do not really need to save on one copy/move operation, in which case you should favor clarity and simplicity (e.g. take by reference to const).

This said, if you are concerned about the overhead of forwarding your constructor's arguments, you can make your constructor a constructor template and use perfect forwarding to incur minimum overhead no matter whether you are passing an rvalue or an lvalue:

class Person
{
    public:
        template<typename T, typename U>
        Person(T&& name, U&& surname)
            : _name(std::forward<T>(name)), _surname(std::forward<U>(surname)) { }
        ...
    private:
        string _name;
        string _surname;
};

class Student : public Person
{
    public:
        template<typename T, typename U, typename V>
        Student(T&& name, U&& surname, V&& schedule)
            : Person(
                std::forward<T>(name), 
                std::forward<U>(surname)), 
                _schedule(std::forward<V>(schedule)) 
        { }
        ...
    private:
        Schedule _schedule;
};


来源:https://stackoverflow.com/questions/15449397/should-move-semantics-be-used-in-constructor-chains

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!