【C++】インスタンス生成の7つの方法
目次
- インスタンス生成とは
- スタックでのインスタンス生成
- ヒープでのインスタンス生成
- コンストラクタを用いたインスタンス生成
- コピーコンストラクタを使ったインスタンス生成
- ムーブコンストラクタを使ったインスタンス生成
- ファクトリ関数によるインスタンス生成
- スマートポインタによるインスタンス管理
- placement newによるインスタンス生成
インスタンス生成とは
C++における「インスタンス生成」とは、クラスや構造体のオブジェクト(インスタンス)を作成することを指します。C++では、オブジェクトを生成する方法として、スタックに作成する方法と、ヒープに作成する方法の2つがあります。
スタックでのインスタンス生成
スタックでのインスタンス生成は、関数のスコープ内で変数としてオブジェクトを作成する方法です。スコープを抜けると自動的に破棄されます。
class Sample {
public:
Sample() { std::cout << "Sampleのコンストラクタ" << std::endl; }
~Sample() { std::cout << "Sampleのデストラクタ" << std::endl; }
};
void func() {
Sample obj; // スタック上にオブジェクトを作成
} // スコープを抜けると自動的にデストラクタが呼ばれる
ヒープでのインスタンス生成
ヒープ上にオブジェクトを作成するには new
演算子を使用します。ヒープに確保されたメモリは明示的に解放する必要があります。
void func() {
Sample* obj = new Sample(); // ヒープ上にオブジェクトを作成
delete obj; // 明示的に解放しないとメモリリークの原因になる
}
コンストラクタを用いたインスタンス生成
コンストラクタは、オブジェクトが作成される際に自動的に呼ばれる関数です。
class Sample {
public:
int x;
Sample(int val) : x(val) {
std::cout << "値 " << x << " で初期化" << std::endl;
}
};
void func() {
Sample obj1(10);
Sample* obj2 = new Sample(20);
delete obj2;
}
コピーコンストラクタを使ったインスタンス生成
コピーコンストラクタを用いると、既存のオブジェクトを元に新しいオブジェクトを作成できます。
class Sample {
public:
int x;
Sample(int val) : x(val) {}
Sample(const Sample& other) : x(other.x) {
std::cout << "コピーコンストラクタ" << std::endl;
}
};
void func() {
Sample obj1(10);
Sample obj2 = obj1; // コピーコンストラクタが呼ばれる
}
ムーブコンストラクタを使ったインスタンス生成
ムーブコンストラクタを用いると、一時オブジェクトを効率的に新しいオブジェクトに移動できます。
class Sample {
public:
int* x;
Sample(int val) : x(new int(val)) {}
Sample(Sample&& other) noexcept : x(other.x) {
other.x = nullptr;
std::cout << "ムーブコンストラクタ" << std::endl;
}
~Sample() { delete x; }
};
void func() {
Sample obj1(10);
Sample obj2 = std::move(obj1); // ムーブコンストラクタが呼ばれる
}
ファクトリ関数によるインスタンス生成
ファクトリ関数を使うことで、オブジェクトの生成処理を一元化できます。
std::unique_ptr createSample(int val) {
return std::make_unique(val);
}
void func() {
auto obj = createSample(10);
}
スマートポインタによるインスタンス管理
std::unique_ptr
や std::shared_ptr
を使うと、メモリ管理が簡単になります。
void func() {
std::unique_ptr obj1 = std::make_unique(10);
std::shared_ptr obj2 = std::make_shared(20);
}
placement newによるインスタンス生成
特定のメモリ領域にオブジェクトを配置するには placement new
を使用します。
void func() {
char buffer[sizeof(Sample)];
Sample* obj = new(buffer) Sample(10);
obj->~Sample();
}