トップページ – Modern C++編 C++編](../../index.html) – 第14章
問題① この章で使った 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
コピーとムーブに関するメンバ関数を明示的に実装するのなら、デストラクタも実装するべきですし、大抵は必要性があります。
なお、ムーブを行った後、ムーブ元になったオブジェクトは使ってはいけません。
Programming Place Plus のトップページへ
| はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
| X で ポスト/フォロー | LINE で送る | noteで書く |
|
|
管理者情報 | プライバシーポリシー |