应该在构造函数链中使用移动语义吗?

时间:2013-03-16 12:41:02

标签: c++ c++11 move-semantics

假设我有以下两个类:

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

这是移动语义的良好用法吗?正如您所看到的,Student构造函数中有一层'move-s'。是否可以避免move函数调用开销而不使用const引用将参数转发给基础构造函数?

或者也许......每当我需要将参数转发给基础构造函数时,我应该使用const引用吗?

2 个答案:

答案 0 :(得分:4)

没有。对于尺寸非常大的类型,您只会获得性能提升,但非常罕见。当然,在处理你事先不知道的某种类型时,移动或移动是非常昂贵的,然后假设便宜的移动。

你现有的代码是惯用的C ++ 11,在这方面一个完美的转发构造函数是错误的,并且可能会破坏一个参数来启动。

答案 1 :(得分:2)

在选择优化之前,请考虑支持代码可读性和简单性。您很可能不需要保存一个复制/移动操作,在这种情况下,您应该支持清晰和简单(例如,参考const)。

这就是说,如果您担心转发构造函数参数的开销,可以使构造函数成为构造函数模板并使用完美转发来产生最小的开销无论你是在传递右值还是左值:

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