コンストラクター: 戻り値の型宣言のない、クラスと同じ名前の関数がコンストラクターです。
コンストラクターの分類: パラメーターなしコンストラクター、パラメーター化されたコンストラクター、代入 (コピー) コンストラクター
Test() //无参构造函数定义 Test(inta, int b) //有参构造函数定义 Test(const Test &obj) //拷贝构造函数定义
3 種類のコンストラクターについては以下で説明します
1. パラメーターなしコンストラクター
メソッドの呼び出し: Test t1 , t2;わかりやすい
2 パラメトリックコンストラクター
3 つの呼び出しメソッド:
class Test5 { public: Test5(inta); Test5(int a, int b); } void main() { Test5 t1(10); //c++编译器默认调用有参构造函数 括号法 Test5 t2 = (20, 10); //c++编译器默认调用有参构造函数 等号法 Test5 t3 = Test5(30); //程序员手工调用构造函数 产生了一个对象 直接调用构造构造函数法 }
3. コピーコンストラクター
なぜコピーコンストラクターがあるのか - クラスオブジェクトのコピー問題を解決するためです
通常のタイプのオブジェクトの場合、それらの間でコピーします例:
int a=88; int b=a;
しかし、クラスオブジェクトの内部構造は通常より複雑で、さまざまなメンバー変数があります。クラスオブジェクトのコピーの簡単な例を見てみましょう。
#include <iostream> using namespace std; class CExample { private: int a; public: CExample(int b) { a=b;} void Show () { cout<<a<<endl; } }; int main() { CExample A(100); CExample B=A; B.Show (); return 0; }
プログラムを実行すると、画面に 100 が出力されます。上記のコードの実行結果から、システムがオブジェクト B にメモリを割り当て、オブジェクト A のコピー プロセスを完了したことがわかります。クラス オブジェクトに関する限り、同じ型のクラス オブジェクトのコピー プロセス全体がコピー コンストラクターを通じて完了します。次の例は、コピー コンストラクターの作業プロセスを示しています。
#include <iostream> using namespace std; class CExample { private: int a; public: CExample(int b) { a=b;} CExample(const CExample& C) { a=C.a; } void Show () { cout<<a<<endl; } }; int main() { CExample A(100); CExample B=A; B.Show (); return 0; } CExample(const CExample& C)
はカスタム コピー コンストラクターです。コピー コンストラクターは特殊なコンストラクターであることがわかります。関数の名前はクラス名と一致している必要があります。このパラメーターは const 型であり、不変です。たとえば、クラス X のコピー コンストラクターの形式は X(X& x) です。
初期化されたカスタム クラス タイプ オブジェクトを使用して、新しく構築された別のオブジェクトを初期化すると、コピー コンストラクターが自動的に呼び出されます。つまり、クラスのオブジェクトをコピーする必要がある場合、コピー コンストラクターが呼び出されます。コピー コンストラクターは次の状況で呼び出されます:
オブジェクトが値によって関数本体に渡される
オブジェクトが値によって関数から返される
オブジェクトは別のオブジェクトによって初期化される必要がある。
クラス内でコピー コンストラクターを明示的に宣言しない場合、コンパイラーはデフォルトのコピー コンストラクターを自動的に生成し、オブジェクト間のビット コピーを完了します。ビットコピーはシャローコピーとも呼ばれますが、これについては後述します。
カスタム コピー コンストラクターは優れたプログラミング スタイルであり、コンパイラーがデフォルトのコピー コンストラクターを形成するのを防ぎ、ソース コードの効率を向上させることができます。
浅いコピーと深いコピー
場合によっては、クラス内のメンバー変数はヒープ メモリを動的に割り当てる必要があります。ビット コピーが実行されると、オブジェクト内の値が別のオブジェクトに完全にコピーされます (A=B など)。このとき、B のメンバ変数ポインタがメモリを割り当てている場合、A のメンバ変数も同じメモリを指します。これにより問題が発生します。B がメモリを解放すると (破壊など)、A のポインタがワイルド ポインタになり、実行時エラーが発生します。
ディープコピーとシャローコピーは、単純に理解すると、クラスがリソースを持っている場合、このクラスのオブジェクトがコピーされると、リソースが再割り当てされ、逆に、リソースが存在しない場合、このプロセスはディープコピーになります。再割り当てされた場合、それは浅いコピーになります。以下はディープコピーの例です。
#include <iostream> using namespace std; class CA { public: CA(int b,char* cstr) { a=b; str=new char[b]; strcpy(str,cstr); } CA(const CA& C) { a=C.a; str=new char[a]; //深拷贝 if(str!=0) strcpy(str,C.str); } void Show() { cout<<str<<endl; } ~CA() { delete str; } private: int a; char *str; }; int main() { CA A(10,"Hello!"); CA B=A; B.Show(); return 0; }
ディープ コピーとシャロー コピーの定義は、次のように単純に理解できます: クラスがリソース (ヒープ、またはその他のシステム リソース) を所有している場合、このクラスのオブジェクトがコピーされるとき、このプロセスは ディープ コピー と呼ばれます。一方、オブジェクトにリソースがあるにもかかわらず、そのリソースがコピー プロセス中にコピーされない場合、それは浅いコピーとみなされます。
リソースを浅くコピーした後、リソースが解放されると、リソースの所有権が不明瞭になり、プログラムの実行エラーが発生します。
Test (Test &c_t) はカスタム コピー コンストラクターの名前はクラス名と一致している必要があり、関数の仮パラメーターはこの型の参照変数である必要があります。
すでに初期化されたカスタム クラス タイプ オブジェクトを使用して、新しく構築された別のオブジェクトを初期化する場合、カスタム コピー コンストラクターがない場合は、コピー コンストラクターが自動的に呼び出され、これを完了するためにデフォルトのコピー コンストラクターが提供されます。上記のコードのコアとなるコピー ステートメントは、Test (Test &c_t) コピー コンストラクターの p1=c_t.p1; プロセスによって完了します。
上記は C++ レビューの重要なポイントの 3 番目の要約です - コンストラクターの内容 詳細については、PHP 中国語 Web サイト (m.sbmmt.com) に注目してください。