目次
ヾ(๑╹◡╹)ノ「人は常に過去の怠惰の代償を払わなければなりません!ヾ(๑╹◡╹)ノ」
1. クラスの 6 つのデフォルトのメンバー関数
デフォルトのメンバー関数: ユーザーによる明示的な実装を行わずにコンパイラによって生成されたメンバー関数は、デフォルトのメンバー関数と呼ばれます。
2.コンストラクター(*^▽^*)
2.1 コンセプト
データクラスの場合:
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Init(2022, 7, 5);//初始化
d1.Print();
Date d2;
d2.Init(2022, 7, 6);//初始化
d2.Print();
return 0;
}
上記のコードでは、Init public メソッドを通じてオブジェクトの日付を設定し、オブジェクトが作成されるたびにこのメソッドを呼び出して情報を設定できます。
2.2 特徴
class Date
{
public:
// 1.无参构造函数
Date()//构造函数:函数名与类名相同,无返回值
{
_year = 1;
_month = 1;
_day = 1;
}
// 2.带参构造函数
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1; // 调用无参构造函数,注意,不能写成Date d1();
Date d2(2015, 1, 1); // 调用带参的构造函数
// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
}
デフォルトのコンストラクター: (1) 引数のないコンストラクター (2) 完全なデフォルトのコンストラクター (3) C++ コンパイラーによって生成された引数のないコンストラクター [つまり、デフォルトのコンストラクターがない場合は、3 つのうちの 1 つが必要です] 記述されたコンストラクターパラメータなしではなく、すべてがデフォルトでもありません]エラーが報告されます]
クラスのメンバーがすべてカスタム型の場合、デフォルトで生成された関数を使用できます。組み込み型関数のメンバーがある場合、またはパラメーターの初期化を表示する必要がある場合は、コンストラクターを自分で実装する必要があります。(初期化するにはパラメータを渡す必要があり、コンストラクターを自分で実装する必要があります) [ほとんどの場合、コンストラクターを自分で作成します]
C++ コンパイラによって生成されるデフォルト コンストラクターは、組み込み型関数のメンバー変数を処理せず、カスタム型メンバーは独自のデフォルト コンストラクターを呼び出します。
注: C++11 では、組み込み型のメンバーが初期化されない、つまり、 クラスで宣言されたときに組み込み型のメンバー変数に デフォルト値が与えられる という欠陥に対してパッチが適用されました。[注: これは宣言であるため、初期化ではなくデフォルト値です]
class Date
{
public:
Date()//无参的构造函数
{
_year = 1900;
_month = 1;
_day = 1;
}
Date(int year = 1900, int month = 1, int day = 1)//全缺省的构造函数
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void Test()
{
Date d1;//这里会发生错误,默认构造函数只能有一个
}
実行時にエラーが発生し、競合が発生します。
一般に、C++ クラスは独自のコンストラクターを作成する必要があります。コンパイラーに自動的に生成させることができるのは、まれなケースだけです。
(1) クラス内のメンバーはすべて自己定義型のメンバーであり、これらのメンバーはデフォルトのコンストラクターを提供します。
(2) 組み込み型メンバの宣言時にデフォルト値が与えられます。
3. デストラクター(*^▽^*)
3.1 コンセプト
3.2 特徴
4. コンストラクターをコピーします(*^▽^*)
4.1 コンセプト
オブジェクトが作成されると、オブジェクトとまったく同じ新しいオブジェクトが作成されます。
4.2 特徴
1.コピー コンストラクターは、コンストラクターのオーバーロード形式です。
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)//拷贝构造函数
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(d1);
return 0;
}
値を渡す方法: コピー コンストラクターを呼び出すと、コピー コンストラクターが呼び出されます。この関数を呼び出すには、最初にパラメーターを渡す必要があります。パラメーターを渡すことは、一時コピーです。このとき、状態は一時コピー オブジェクトであり、これは次と同等です。コピー構築で、コピー構築関数を呼び出す必要がある場合、この時点で無限再帰呼び出しがトリガーされます。
パラメーターを参照によって渡す: コピー構築は呼び出されません。
[オブジェクトはこのクラスの別のオブジェクトを初期化します。これはコピー構築です] [オブジェクトのコピーはコピー構築です]
カスタム タイプのオブジェクトの場合、コピーの初期化は、コピー コンストラクターを呼び出して完了する必要があります。
結論: 一般的なクラスの場合、自己生成されたコピー構造で十分であり、コピー構造を自分で記述する必要はありません。ただし、スタックのようなリソースを自分で直接管理するクラスの場合は、ディープ コピーを自分で実装する必要があります。
クラスにリソース アプリケーションが関与していない場合は、コピー コンストラクターを記述してもしなくても構いません。リソース アプリケーションが関与すると、コピー コンストラクターを記述する必要があります。それ以外の場合は、コピー コンストラクターは浅いコピーになります。
プログラムの効率を高めるため、一般オブジェクトにパラメータを渡す場合は、できるだけ参照型を使用し、返すときも現場に合わせて可能な限り参照を使用するようにしてください。
5. 代入演算子のオーバーロード(*^▽^*)
5.1 演算子のオーバーロード
//日期的判断是否相等
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year
&& d1._month == d2._month
&& d1._day == d2._day;
}
//放到类里面 Date,此时是在类外面的写法
//1.
if (operator==(d1, d2))
{
cout << "==" << endl;
}
//2/
if (d1 == d2)
{
cout << "==" << endl;
}
//1.和2.是等价的,编译器会处理成1.
(1) 組み込み型はさまざまな演算子を直接使用できますが、カスタム型はさまざまなアルゴリズムを直接使用できません。カスタム型でさまざまな演算子を使用できるようにするために、演算子のオーバーロードがあります。
(2) 関数パラメータはオペランドと同数あります。(== 2 つのオペランド; ++ 1 つのオペランド;)
クラスで書きました:
//日期的判断是否相等
bool operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
//放到类里面 Date,此时是在类里面的写法
//1.
if (d1.operator==(d2))
{
cout << "==" << endl;
}
//2/
if (d1 == d2)
{
cout << "==" << endl;
}
//1.和2.是等价的,编译器会处理成对应重载运算法调用
両方のコードが存在する場合 (関数のオーバーロードに準拠しているため、コンパイラーはパスできます)、コンパイラーはクラス内の演算子のオーバーロードを最初に使用します。
//判断日期小
bool operator<(const Date& d)
{
//小的情况
if (_year < d._year
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && _day < d._day))
{
return true;
}
else
{
return false;
}
}
ここでは細部にまで注意を払います。当然のことと思われないでください。
5.2 代入演算子のオーバーロード
1. パラメータの種類2. 戻り値3. 自分自身に値を割り当てているかどうかを確認します4. *こちらを 返却5. クラスが代入演算子のオーバーロードを明示的に定義していない場合、コンパイラはオブジェクトのバイト順の値のコピーを完成させるために代入演算子のオーバーロードも生成します。
//d2 = d1;-> d2.operator(&d2, d1)
Date& operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
int main()
{
Date d1(2000, 8, 20);
Date d2(2000, 9, 17);
Date d3(d1);//拷贝构造,一个存在的对象去初始化另一个要创建的对象
d2 = d1;//赋值重载(复制拷贝) 两个已经存在的对象之间赋值
}
補足:ヌルポインタは存在しないのでしょうか?が存在し、空のアドレスは既存のアドレスです。