第 9 章: C++ コンストラクターとデストラクターの詳細な説明
1。概要
C++ では、コンストラクターとデストラクターは、オブジェクトの初期化とオブジェクト リソースのクリーンアップに使用される特別なメンバー関数です。コンストラクターはオブジェクトの初期化を完了する責任を負い、デストラクターはオブジェクトのライフサイクルの終了時にリソースをクリーンアップする責任を負います。
2. コンストラクター
コンストラクターは、クラスと同じ名前を持ち、戻り値の型を持たない特殊なメンバー関数です。これは、必要な初期化操作を実行するためにオブジェクトが作成されるときに自動的に呼び出されます。
2.1 コンストラクタの定義
各クラスには 1 つ以上のコンストラクターを含めることができます。パラメーター リストによれば、コンストラクターはパラメーターなしのコンストラクターとパラメーター化されたコンストラクターに分類できます。
class MyClass {
public:
// 无参构造函数
MyClass() {
// 初始化代码
}
// 有参构造函数
MyClass(int value) {
// 初始化代码
}
};
2.2 コンストラクター呼び出し
コンストラクターはオブジェクトの作成時に自動的に呼び出されるため、明示的にコンストラクターを呼び出す必要はありません。オブジェクトを作成するとき、コンパイラーは、指定されたパラメーターに基づいて呼び出す適切なコンストラクターを照合します。
MyClass obj1; // 调用无参构造函数创建对象
MyClass obj2(100); // 调用有参构造函数创建对象
2.3 初期化リスト
コンストラクターの初期化リストを使用してメンバー変数を初期化できます。初期化子リストを使用すると、より効率的な初期化方法が提供され、メンバー変数が正しい順序で初期化されることが保証されます。
class MyClass {
private:
int value;
double scale;
public:
MyClass(int v, double s) : value(v), scale(s) {
// 初始化代码
}
};
2.4 デフォルトのコンストラクター
クラスにコンストラクターが定義されていない場合、コンパイラーはデフォルトのコンストラクターを自動的に生成します。デフォルトのコンストラクターはパラメーターを受け取らず、初期化も実行しません。ただし、他のコンストラクターがカスタマイズされると、コンパイラーはデフォルトのコンストラクターを生成しなくなります。
class MyClass {
public:
// 自定义构造函数
MyClass(int value) {
// 初始化代码
}
// 编译器不会生成默认构造函数
};
2.5 コピーコンストラクター
コピー コンストラクターは、新しいオブジェクトを作成し、既存のオブジェクトで初期化するために使用される特別なコンストラクターです。値または参照によって呼び出すことができます。
class MyClass {
public:
// 拷贝构造函数
MyClass(const MyClass& other) {
// 初始化代码,使用other对象的值来初始化新的对象
}
};
MyClass obj1; // 调用无参构造函数创建对象obj1
MyClass obj2(obj1); // 调用拷贝构造函数创建对象obj2,使用obj1的值来初始化
3. デストラクター
デストラクターは、クラスと同じ名前を持つ特殊なメンバー関数ですが、先頭にチルダ (~) が付いています。オブジェクトによって占有されているリソースを解放するために使用されます。
3.1 デストラクタの定義
各クラスはデストラクターを 1 つだけ持つことができ、戻り値の型がなく、パラメーターを受け入れません。
class MyClass {
public:
// 析构函数
~MyClass() {
// 清理资源的代码
}
};
3.2 デストラクタ呼び出し
デストラクターはオブジェクトが破棄されるときに自動的に呼び出され、手動で明示的に呼び出すことはできません。デストラクターは、オブジェクトがスコープ外になったとき、オブジェクトへのポインターが削除されたとき、またはプログラムが終了したときに呼び出されます。
void Function() {
MyClass obj; // 对象obj在该函数块结束时将被销毁,自动调用析构函数
}
int main() {
MyClass* ptr = new MyClass(); // 使用new动态创建对象,需要手动delete释放内存
delete ptr; // 调用析构函数后释放内存
return 0;
}
3.3 デストラクタの適用
デストラクターは、オブジェクトによって占有されているメモリ、ファイル ハンドル、ネットワーク接続などのリソースを解放するためによく使用されます。リソース リークは、デストラクターで必要なクリーンアップ操作を実行することで回避できます。
class FileManager {
private:
FILE* file;
public:
FileManager(const char* filename) {
file = fopen(filename, "r"); // 打开文件
if (!file) {
// 处理打开文件失败的情况
}
}
~FileManager() {
if (file) {
fclose(file); // 关闭文件
}
}
};
4. 事例:図書館管理システム
以下は、コンストラクターとデストラクターの動作を示す簡単なライブラリ管理システムの例です。
#include <iostream>
#include <vector>
using namespace std;
// Book类表示图书对象
class Book {
private:
string title;
string author;
public:
Book(const string& t, const string& a) : title(t), author(a) {
cout << "Book \"" << title << "\" by " << author << " created." << endl;
}
~Book() {
cout << "Book \"" << title << "\" by " << author << " destroyed." << endl;
}
void display() {
cout << "Title: " << title << endl;
cout << "Author: " << author << endl;
}
};
// Library类表示图书馆
class Library {
private:
vector<Book> books;
public:
void addBook(const Book& book) {
books.push_back(book);
}
void displayAllBooks() {
for (const auto& book : books) {
book.display();
cout << endl;
}
}
};
int main() {
Library library;
library.addBook(Book("Harry Potter", "J.K. Rowling"));
library.addBook(Book("To Kill a Mockingbird", "Harper Lee"));
library.displayAllBooks();
return 0;
}
操作結果:
Book "Harry Potter" by J.K. Rowling created.
Book "To Kill a Mockingbird" by Harper Lee created.
Title: Harry Potter
Author: J.K. Rowling
Title: To Kill a Mockingbird
Author: Harper Lee
Book "Harry Potter" by J.K. Rowling destroyed.
Book "To Kill a Mockingbird" by Harper Lee destroyed.
上記のサンプル コードを実行すると、コンストラクターとデストラクターが呼び出されていることがわかります。book オブジェクトを作成するときに、コンストラクターが呼び出され、オブジェクトのメンバー変数が初期化され、対応するプロンプト情報が出力されます。そして、プログラムが終了するか、書籍オブジェクトがライブラリから削除されると、デストラクタが呼び出され、オブジェクトが占有していたリソースが解放され、対応する破棄情報が出力されます。