[C++ Basics: 21]: 友人 友人は 4 つの質問をします。友人とは何ですか? フレンドクラス?フレンド機能?フレンドをいつ使用するか?

この一連のC++ 関連記事は、あくまで著者の学習メモであり、私自身の理解に基づいて学習を記録していきます。C++ 学習シリーズは、基礎、STL、および高度なデータ構造とアルゴリズムの3 つの段階に分かれており、関連する主な内容は次のとおりです。

  1. 基本:クラスとオブジェクト(C++ の 3 つの主要な機能など)。
  2. STL : C++ が提供する STL 関連ライブラリの使用方法を学びます
  3. 高次データ構造とアルゴリズム:独自の 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キーワードを追加する必要があります。 。


  1. フレンド関数は、クラスのプライベートおよび保護されたメンバーにアクセスできますが、クラスのメンバー関数にはアクセスできません。
  2. フレンド関数は const で変更できません。
  3. フレンド関数はクラス定義内のどこでも宣言でき、クラスのアクセス修飾子によって制限されません。
  4. 関数は複数のクラスのフレンド関数になることができます。
  5. フレンド関数の呼び出し原理は通常の関数と同じです。

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. 友達はいつ使うべきですか?

友達とは何なのか、そしてその役割は何なのかを思い出してください。: フレンドはカプセル化を突破する方法を提供し、場合によっては利便性を提供します。ただし、フレンドはカップリングを増加させ、カプセル化を破壊するため、フレンドを複数回使用しないでください。


上記のフレンド関数とフレンド クラスの例を簡単にまとめます。

  1. ストリーム入力/ストリーム出力をオーバーロードする必要がある場合! (cout/cin);
  2. クラスが特定の関係を持つ別のクラスのメンバー変数にアクセスする必要がある場合に使用されます。[端的に言えば、クラスのカプセル化の制限を突破したい場合に使用します]

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 であってもよいか?) | このポインターはどこに存在しますか?

おすすめ

転載: blog.csdn.net/weixin_53202576/article/details/131037673