一つ、バラバラ
C ++の特徴はオブジェクト指向です。オブジェクトを作成するには、コンストラクターを呼び出す必要があります。コンストラクターの本来の目的は、オブジェクトが作成されたときにオブジェクトを初期化することであり、コンパイラーは、渡された実際のパラメーターに従って、異なる(オーバーロードされた)コンストラクターと一致します。コンストラクターのさまざまな機能に応じて、コンストラクターは、デフォルトコンストラクター、通常のコンストラクター、コピーコンストラクター、変換コンストラクターに分けることができます。次の表に、これらのさまざまなタイプのコンストラクターの機能を簡単に示します。
関数タイプ | 特徴 |
---|---|
デフォルトのコンストラクタ | コンパイラーによって自動的に生成されるコンストラクター |
通常のコンストラクター | ユーザー定義のコンストラクター |
コピーコンストラクタ | コピーによるオブジェクトの初期化 |
変換コンストラクター | 他のタイプを現在のクラスタイプのオブジェクトに変換します |
一見すると、非常に多くのコンストラクターは非常に困難です。実際、コンストラクターをオーバーロードするには、関数のポリモーフィズム(コンストラクターは主にパラメーターの受け渡しが異なります)を使用する必要があります。作者は、このような詳細に分割する必要はないと考えています。前述のように、コンストラクターの本来の目的は、オブジェクトの作成時にオブジェクトを初期化することであり、コンパイラーは、渡されたさまざまなパラメーターに従ってさまざまなコンストラクターを呼び出します。で(これはかなり賢いようです)。本質的には、オブジェクトを初期化するためにコンストラクターが呼び出されます。コンストラクターをこのような詳細な説明に分割するのは、説明の便宜上です。「コンストラクター1、コンストラクター2、コンストラクター3 ...」の使用は、「デフォルト」とはほど遠いものです。コンストラクター、コピーコンストラクター、変換コンストラクター...」とても美しいですね。。でも、名前がたくさんあるので、私のような初心者は変で怖いように見えます。実際、理解するのは難しいことではありません。このブログは、シャオバイに初心者の村の戦略全体を提供するためのものであり、彼自身の理解を深めるためのものです。
たとえば、Complex
複素数クラスができました。複素数オブジェクトを作成する場合Complex();
は、パラメーターがないため、デフォルトのコンストラクターを呼び出します。使用する場合Complex(1,2)
は、通常のコンストラクターを呼び出します。これを使用する場合Complex(c1)
は、コピーコンストラクターを呼び出します。受信パラメーターは複合型c1であるため、使用するComplex(1.0)
場合は、変換コンストラクターが呼び出されます。
もちろん、これらのコンストラクターを定義する前に、これらの複雑なオブジェクトをそれほど恣意的に作成することはできません。以下に複素数の例を示します。
2、例
#include <iostream>
using namespace std;
//复数类
class Complex {
public:
Complex() : m_real(0.0), m_imag(0.0) {
} //默认构造函数
Complex(double real, double imag) : m_real(real), m_imag(imag) {
} //普通构造函数
Complex(double real) : m_real(real), m_imag(0.0) {
} //转换构造函数
Complex(const Complex &c) : m_real(c.m_real),m_imag(c.m_imag) {
} //拷贝构造函数
public:
friend ostream & operator<<(ostream &out, Complex &c); //友元函数
double get_real() {
return m_real; }
double get_imag() {
return m_imag; }
private:
double m_real; //实部
double m_imag; //虚部
};
//重载>>运算符
ostream & operator<<(ostream &out, Complex &c) {
out << c.m_real << " + " << c.m_imag << "i";;
return out;
}
int main() {
Complex a;
cout << "默认构造函数 Complex():" << endl;
cout << a << endl;
cout << "普通构造函数 Complex(10.0, 20.0):" << endl;
a=Complex(10.0, 20.0);cout << a << endl;
cout << "转换构造函数 Complex(25.5):" << endl;
a = 25.5; //调用转换构造函数
cout << a << endl;
cout << "拷贝构造函数 Complex(a):" << endl;
Complex b = a;
cout << b << endl;
cin.get();
return 0;
}
出力は次のとおりです。
默认构造函数 Complex():
0 + 0i
普通构造函数 Complex(10.0, 20.0):
10 + 20i
转换构造函数 Complex(25.5):
25.5 + 0i
拷贝构造函数 Complex(a):
25.5 + 0i
実際、上記のコードにデフォルトコンストラクターとコピーコンストラクターの定義がない場合、コンパイラーはデフォルトコンストラクターとコピーコンストラクターのコードを自動的に追加するため、正常に実行できます。クラスにポインタ変数と動的メモリ割り当てがある場合は、コピーコンストラクタを手動で定義する必要があることに注意してください。
オブジェクトの作成時にオブジェクトを初期化するだけでなく、他の場合にもコンストラクターが呼び出されます。たとえば、オブジェクトがコピーによって初期化されるときにコピーコンストラクター(上記b=a
)が呼び出され、他のタイプをに変換するときに変換構造が呼び出されます。現在のクラスタイプ。関数(上記a=25.5
)。他の状況で呼び出されるこれらのコンストラクターは、特別なコンストラクターになります。特別なコンストラクターは、必ずしもコンストラクターの本来の意図を反映しているわけではありません。実際、いわゆる「特別なコンストラクター」はComplex(10.0, 20.0)
、通常のコンストラクターを直接呼び出すなど、暗黙的にコンストラクターを呼び出すだけです。これは、変換コンストラクターa = 25.5;
をa=Complex(25.5)
暗黙的に呼び出すことと同じです。
3、コピーコンストラクタ
コピーコンストラクターに関しては、次の点に注意する必要があります。
1.コピーコンストラクターを呼び出すためのいくつかの手順:
- たとえば、テストオブジェクトが仮パラメータに渡された場合、一時変数が最初に生成されます。これをCと呼びましょう。
- 次に、コピーコンストラクターを呼び出して、Cにtestの値を指定します。
- 関数の実行後、Cオブジェクトは破棄されます。
2.コピーコンストラクターは、単一のパラメーターを持つ特別なコンストラクターです。パラメーター(通常はconstによって変更されます)は、クラスタイプへの参照です。新しいオブジェクトが定義され、同じタイプのオブジェクトで初期化されると、コピーコンストラクターが表示されます。このタイプのオブジェクトが関数に渡されるか、このタイプのオブジェクトが関数から返されると、コピーコンストラクターは暗黙的に呼び出されます。言い換えると、
A x(2); //直接初始化,调用构造函数
A y = x; //拷贝初始化,调用拷贝构造函数
3.コピーコンストラクターを定義する必要がある状況:
- クラス型メンバーまたは組み込み型(ポインター型ではない)メンバーのみを含むクラスは、コピーコンストラクターを明示的に定義せずにコピーできます。
- 一部のクラスには、ポインターであるデータメンバーがあるか、コンストラクターで割り当てられた他のリソースを表すメンバーがあります。この場合、コピーコンストラクターを定義する必要があります。
4.いつコピーコンストラクタを使用しますか?
クラスのオブジェクトをコピーする必要がある場合、コピーコンストラクターが呼び出され、次の状況でコピーコンストラクターが呼び出されます。
- オブジェクトは値によって関数本体に渡されます
- オブジェクトは関数から値で返されます
- 1つのオブジェクトを別のオブジェクトで初期化する必要があります
参照
C言語中国語ネットワーク
新人チュートリアル