// 適切なメモリ管理の例
class ResourceManager {
private:
int* data;
size_t size;
public:
// コンストラクタ
ResourceManager(size_t n) : size(n) {
data = new int[size];
std::fill_n(data, size, 0);
}
// デストラクタ
~ResourceManager() {
delete[] data;
}
// コピーコンストラクタ
ResourceManager(const ResourceManager& other) : size(other.size) {
data = new int[size];
std::copy(other.data, other.data + size, data);
}
// コピー代入演算子
ResourceManager& operator=(const ResourceManager& other) {
if (this != &other) {
// 自己代入を処理するための一時変数を作成
int* temp = new int[other.size];
std::copy(other.data, other.data + other.size, temp);
// 古いリソースをクリーンアップ
delete[] data;
// 新しいリソースの所有権を取得
data = temp;
size = other.size;
}
return *this;
}
};
C++でクラスのメモリリソースを適切に管理するには、3つの重要な関数を実装する必要があります:デストラクタ、コピーコンストラクタ、コピー代入演算子。基本概念を復習する必要がありますか?数学的原理ガイドをご覧ください。他の実装を探していますか?Excelの公式またはPythonスクリプトのガイドをお試しください、または迅速な計算のために計算機を使用してください。
自分で試してみよう:三数法則の実装
C++での三数法則の動作を確認:
class StringWrapper {
private:
char* data;
public:
// コンストラクタ
StringWrapper(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
// デストラクタ
~StringWrapper() {
delete[] data;
}
// コピーコンストラクタ
StringWrapper(const StringWrapper& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
// コピー代入演算子
StringWrapper& operator=(const StringWrapper& other) {
if (this != &other) {
delete[] data;
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
return *this;
}
// デモ用のゲッター
const char* getData() const { return data; }
};
int main() {
// 元のオブジェクトを作成
StringWrapper str1("こんにちは");
// コピーコンストラクタを使用
StringWrapper str2 = str1;
// 代入演算子を使用
StringWrapper str3("世界");
str3 = str1;
return 0;
}
重要なポイント
- クラスが動的メモリを管理する場合、デストラクタ、コピーコンストラクタ、コピー代入演算子を実装します
- 常に自己代入をチェックし、例外安全性を考慮します
- モダンC++では、スマートポインタまたはSTLコンテナを使用して手動メモリ管理を回避します
- C++11以降を使用する場合は、ムーブセマンティクスのための五の法則も考慮します
- 可能な限り、生のポインタよりもRAII原則とスマートポインタを優先します