2

次の 2 つのクラスがあるとします。

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 参照を使用する必要がありますか?

4

2 に答える 2

4

いいえ。非常にまれですが、サイズが非常に大きい型の場合にのみパフォーマンスが向上します。もちろん、移動するのに非常にコストがかかる、または移動できないタイプを事前に知らない場合は、安価な移動を想定してください。

あなたの既存のコードは慣用的な C++11 であり、この点で完全な転送コンストラクターは間違っており、起動する 1 つのパラメーターで恐ろしく壊れてしまいます。

于 2013-03-16T13:30:42.327 に答える
2

最適化を選択する前に、コードの読みやすさと単純さを優先することを検討してください。1 回のコピー/移動操作で保存する必要がない可能性が非常に高く、その場合は明確さと単純さを優先する必要があります (たとえば、 を参照して取得します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;
};
于 2013-03-16T12:44:29.890 に答える