この一連のC++ 関連記事は、あくまで著者の学習メモであり、私自身の理解に基づいて学習を記録していきます。C++ 学習シリーズは、基礎、STL、および高度なデータ構造とアルゴリズムの3 つの段階に分かれており、関連する主な内容は次のとおりです。
- 基本:クラスとオブジェクト(C++ の 3 つの主要な機能など)。
- STL : C++ が提供する STL 関連ライブラリの使用方法を学びます。
- 高次データ構造とアルゴリズム:独自の STL ライブラリを手動で実装し、 B ツリー、B+ ツリー、赤黒ツリーなどの高次データ構造を設計および実装します。
学習セット:
今回の内容:【C++の基礎:21】:友達に関する4連続質問:友達って何?フレンドクラス?フレンド機能?フレンドをいつ使用するか?
目次:
1. friendsの基本的な理解
2. friends関数
- - 2.1 friends関数の基本的な使い方
- - 2.2 cout/cinのオーバーロード構造の書き方
- - 2.3 friends関数を使用する際の注意点
3. friendsクラス
- - 3.1フレンド クラスの基本的な理解
- - 3.2 例 + 図: フレンド クラスの説明
4. フレンドをいつ使用するか?
5. おすすめ関連記事
[ C++学習集リンク]
1.友達についての基本的な理解
フレンドはカプセル化を突破する方法を提供し、場合によっては利便性を提供します。ただし、フレンドはカップリングを増加させ、カプセル化を破壊するため、フレンドを複数回使用しないでください。
フレンドはフレンド関数とフレンドクラスに分けられ、宣言時のキーワードはフレンドです。
2.フレンド機能
2.1 フレンド機能の基本的な利用シーン
- 主に「ストリーム入力/ストリーム出力」を実装し、 cout/cin をオーバーロードするために使用されます。
cout/cin のオーバーロードのプロセス中、オーバーロードがクラス内にある場合、クラスの最初のパラメーターはデフォルトでこのポインターになります。オーバーロード後、このポインターは左のオペランドとして使用され、実際の cout とは異なります。 /cinの使い方. 犯す!
実際、cout / cin の最初のパラメータは仮パラメータ オブジェクトである必要があります。したがって、対応するオーバーロードをクラス内で宣言および定義することはできません。解決策は、それをグローバル関数として宣言することですが、
次の問題は、クラス内のメンバー変数にクラスの外部からアクセスできないことです。[この時、ヨウユアンはとても良い役割を果たしました!】
2.2 cout / cinのオーバーロード構造体の書き方
cout / cin のオーバーロード構造は次のように記述されます。 [注: 使用頻度が高いため、通常はインライン関数として宣言されます] (これについては後ほど説明します。ここでは理解しておいてください)
// xxx.h
class A{
public:
friend ostream& operator << (ostream& _cout, const A& a);
friend istream& operator >> (istream& _cin, A& a);
};
inline ostream& operator<< (ostream& _cout, const A& a){
_cout << ... << ... << ...;
return _cout;
}
inline istream& operator>> (istream& _cin, A& a){
_cin >> ... >> ... >> ...;
return _cin;
}
2.3 フレンド機能利用時の注意点
フレンド関数は、クラスのプライベートメンバーに直接アクセスできます。クラスの外で定義された通常の関数であり、どのクラスにも属しません。ただし、クラス内で宣言する必要があります。宣言時に、friendキーワードを追加する必要があります。 。
- フレンド関数は、クラスのプライベートおよび保護されたメンバーにアクセスできますが、クラスのメンバー関数にはアクセスできません。
- フレンド関数は const で変更できません。
- フレンド関数はクラス定義内のどこでも宣言でき、クラスのアクセス修飾子によって制限されません。
- 関数は複数のクラスのフレンド関数になることができます。
- フレンド関数の呼び出し原理は通常の関数と同じです。
3. フレンドクラス
3.1 フレンドクラスの基本的な理解
フレンド クラスのすべてのメンバー関数は、別のクラスのフレンド関数になることができ、別のクラスの非パブリック メンバーにアクセスできます。
- 友人関係は一方通行であり、非交換的です。[たとえば、Time クラスと Date クラスの場合、Date クラスを Time クラスのフレンド クラスとして宣言すると、Date クラスで Time クラスのプライベート メンバー変数に直接アクセスできますが、プライベート メンバー変数にアクセスしたい場合は、 TimeクラスのDateクラスのNo. 】
- 友人関係は推移的であってはなりません [C が B の友人であり、B が A の友人である場合、C が A の友人であることを意味することはできません]
- 友人関係は継承できない. 継承の立場について詳しく紹介します。
3.2 例 + 図: フレンドクラスの説明
画像はコードの裏にあります!
#include<iostream>
using std::cout;
using std::endl;
class Time
{
friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:
Time(int hour = 0, int minute = 0, int second = 0)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
void PrintTime() {
cout << _hour << ":" << _minute << ":" << _second << endl;
}
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
void PrintTime() {
_t.PrintTime(); // 直接访问 Time 类的成员函数
}
private:
int _year;
int _month;
int _day;
Time _t;
};
int main() {
// 直接构造一个默认的日期类
Date d1;
d1.PrintTime();
d1.SetTimeOfDate(22, 21, 20);
d1.PrintTime();
return 0;
}
注: 友達関係ではない場合、上記のフォームは公開メンバーのみにアクセスできます。つまり、図には呼び出し関係がなく、エラーが直接報告されます。
4. 友達はいつ使うべきですか?
友達とは何なのか、そしてその役割は何なのかを思い出してください。: フレンドはカプセル化を突破する方法を提供し、場合によっては利便性を提供します。ただし、フレンドはカップリングを増加させ、カプセル化を破壊するため、フレンドを複数回使用しないでください。
上記のフレンド関数とフレンド クラスの例を簡単にまとめます。
- ストリーム入力/ストリーム出力をオーバーロードする必要がある場合! (cout/cin);
- クラスが特定の関係を持つ別のクラスのメンバー変数にアクセスする必要がある場合に使用されます。[端的に言えば、クラスのカプセル化の制限を突破したい場合に使用します]
5. おすすめ関連記事
1. C++ の学習:: [基礎: 05]: C++ 関数のオーバーロードの理解と使用、簡単な紹介: C++ が関数のオーバーロードをサポートする理由 2. C++ の学習:: [基礎: 09]: C++ クラスの理解と基礎 宣言の
定義; C++ のクラスと構造体の違いの簡単な比較
3. C++ 学習:: [基礎: 10]: C++ クラスのアクセス修飾子 (3 種類) とクラスのカプセル化 (3 つの主要機能の 1 つ) の紹介と説明 暫定理解
4. C++ 学習:: [基礎: 11]: C++ クラスと非静的 this ポインターの基本的な使用法 (インタビュー テスト ポイント 2 つ): クラスの null ポインターの問題 (このポインターは null であってもよいか?) | このポインターはどこに存在しますか?