右辺値参照とムーブ 解答ページ | Programming Place Plus Modern C++編【言語解説】 第14章

トップページModern C++編 C++編](../../index.html) – 第14章

Modern C++編は作りかけで、更新が停止しています。代わりに、C++14 をベースにして、その他の方針についても見直しを行った、新C++編を作成しています。
Modern C++編は削除される予定です。

問題①

問題① この章で使った Nameクラスを、コピーとムーブに対応した形で完成させてください。


#include <cstdlib>
#include <cstring>
#include <iostream>
#include <utility>

class Name {
public:
    Name(const char* name)
    {
        mName = static_cast<char*>(std::malloc(std::strlen(name) + 1));
        std::strcpy(mName, name);
    }

    Name(const Name& rhs) : mName(nullptr)
    {
        Copy(rhs);
    }

    Name(Name&& rhs) : mName(nullptr)
    {
        *this = std::move(rhs);
    }

    ~Name()
    {
        std::free(mName);
    }

    Name& operator=(const Name& rhs)
    {
        Copy(rhs);
        return *this;
    }

    Name& operator=(Name&& rhs)
    {
        if (this != &rhs) {
            mName = rhs.mName;
            rhs.mName = nullptr;
        }
        return *this;
    }

    const char* GetName() const
    {
        return mName;
    }

private:
    void Copy(const Name& rhs)
    {
        // 新しい領域を作り、内容をコピー
        char* const n = static_cast<char*>(std::malloc(std::strlen(rhs.mName) + 1));
        std::strcpy(n, rhs.mName);

        // 以前の領域を解放
        std::free(mName);

        // 新しい領域を指すようにポインタを付け替える
        mName = n;
    }

private:
    char*  mName;
};

int main()
{
    Name name1 = "Ken";             // コンストラクタ
    Name name2 = name1;             // コピーコンストラクタ
    Name name3 = std::move(name1);  // ムーブコンストラクタ

    std::cout << name2.GetName() << std::endl;
    std::cout << name3.GetName() << std::endl;

    name1 = name3;                  // コピー代入
    name2 = std::move(name3);       // ムーブ代入
    std::cout << name1.GetName() << std::endl;
    std::cout << name2.GetName() << std::endl;
}

実行結果:

Ken
Ken
Ken
Ken

コピーとムーブに関するメンバ関数を明示的に実装するのなら、デストラクタも実装するべきですし、大抵は必要性があります。

なお、ムーブを行った後、ムーブ元になったオブジェクトは使ってはいけません。



参考リンク


更新履歴

’2017/8/27 新規作成。



第14章のメインページへ

Modern C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る