C ++の3つの主要な機能のカプセル化、継承、およびポリモーフィズム

1CからC ++へ

組み込みソフトウェアの開発プロセスでは、ほとんどの場合、プロセス指向言語であるCを使用して開発します。C言語は、効率の点ですでに非常に効率的です。ハードウェアリソースが不足している組み込みシステムに最適です。ただし、ハードウェアパフォーマンスの向上とハードウェア価格の下落により、C ++は組み込みシステムで徐々に使用されるようになりました。コンパイラがC ++言語用に最適化されると、コード効率はC言語に近くなり、より高度な言語特性を提供します。(C言語はC ++の特性も実現できます。LINUXカーネルは多くのオブジェクト指向のアイデアを使用しています)

2カプセル化

C言語は、structキーワードを使用してカプセル化を実現することもできます。構造体に関数を配置することは、CからC ++への根本的な変更です(C言語は関数ポインターを使用します)。データを関数と一緒にバンドルする機能を使用して、新しいデータ型を作成できます。これはカプセル化と呼ばれます。カプセル化は、データ(属性)と関数(動作)の両方を対象としています。

カプセル化は、現実世界を抽象化したものです。

実際、オブジェクト指向プログラミングは、「オブジェクトにメッセージを送信する」という1つの文に要約できます。実際、行うべきことは、オブジェクトの束を作成してメッセージを送信することだけです。

なぜカプセル化が良いのですか?

  • 凝集
  • 強化されたセキュリティと簡素化されたプログラミング
  • コードの再利用

隠された実装:
C言語では、構造体は他のデータ構造体と同じです。ルールはありません。プログラマーは構造体で好きなことを行うことができ、特別な動作を強制する方法はありません。
構造内のアクセス境界を設定するために、パブリック、プライベート、および保護の3つの新しいキーワードがC ++言語で導入されました。


  • 後で公開を宣言されたすべてのメンバーは、誰でもアクセスできます。

  • タイプの作成者とクラスの内部メンバー関数以外のプライベートには、誰もアクセスできません。
  • Protected
    は、継承構造内の保護されたメンバーにアクセスできますが、プライベートメンバーにはアクセスできません。

classキーワードはC ++で使用されます。これは、C言語の構造体のすべての側面で同じですが、クラスのメンバーがデフォルトでプライベートであり、構造体のメンバーがデフォルトでパブリックである点が異なります。

関数が次のように宣言されている場合友達の場合、これはこのクラスのメンバー関数ではないが、このクラスのプライベートメンバーを変更できるため、このクラスの定義にリストする必要があることを意味します。これは、元のアクセス制御を突破する特権関数です。権限。

3継承

C ++は、新しいクラスを最初から作成するのではなく、作成することによってコードを再利用します。継承は抽象化の昇華です。プログラミングの実践では、共通の特徴が抽出されて親クラスに配置され、クラスには他のサブクラスとは異なる特性があります。(は-関係)
ここに画像の説明を挿入します

サブカテゴリのアクセス許可:

継承 基本クラスのパブリックメンバー 基本クラスの保護されたメンバー 基本クラスのプライベートメンバー
公衆 まだ公開中 まだ保護されています アクセスしない
保護された 保護される まだ保護されています アクセスしない
民間 プライベートになる プライベートになる アクセスしない

組成

構成は、コードを再利用するもう1つの方法です。構成と継承の両方で、サブオブジェクトを新しいタイプに入れることができます。コンポジションは通常、既存のクラスをインターフェイスとして使用するのではなく、新しいクラスに既存のクラスの機能を持たせ、オブジェクトを埋め込んで新しいクラスの機能を実装する場合に使用されます。新しいクラスのユーザーは、新しい定義古いクラスのインターフェイスの代わりに、既存のクラスのプライベートオブジェクトを新しいクラス内に埋め込みます。(持っている-関係)

ここに画像の説明を挿入します
継承と静的メンバー

  • 静的メンバー変数のすべてのサブクラスには、コピーが1つだけあります
  • 静的メンバー変数はクラス外で初期化されます
  • 通常、静的メンバー関数を使用して静的メンバー変数にアクセスします
  • 静的メンバー関数にはこのポインターがなく、オブジェクトの一部ではありません。

4ポリモーフィズム

ポリモーフィズムは、仮想関数によって実現されます。
ポリモーフィズムは、実行時の動的バインディングです。

動的バインディングの条件:

  • 最初:仮想関数として指定されたメンバー関数のみを動的にバインドできます
  • 2番目:関数呼び出しは、基本型の参照またはポインターを介して行う必要があります

基本型の参照またはポインターは、基本型オブジェクトまたは派生型オブジェクトを参照できます。

参照またはポインターの静的型は、C ++がポリモーフィズムをサポートするための基礎となる動的型とは異なる場合があります。基本クラス参照またはポインタを介して基本クラスで定義された関数を呼び出す場合、実行される関数オブジェクトの正確な型を知ることはできません。関数を実行するオブジェクトは、基本クラス型または派生型である可能性があります。

class Base
{
public:
virtual void func(){}
};

class DevidedA :public Base
{
public:
virtual void func(){}
};
class DevidedB :public Base
{
public:
virtual void func(){}
};
/
Base *b = new DevidedB ();
b->func(); //调用 DevidedB::func();

4.1純粋仮想関数

この関数は、純粋仮想関数として定義されています。この関数は、子孫型に対してオーバーライドできるインターフェイスを提供しますが、このクラスでは呼び出されません。さらに、ユーザーはこのクラスのオブジェクトを作成できません。このクラスは抽象基本クラスです。

class Q_WIDGETS_EXPORT QAbstractButton : public QWidget
{
    Q_OBJECT
    ....
protected:
    virtual void paintEvent(QPaintEvent *e) = 0;
    ...
 };

void QRadioButton::paintEvent(QPaintEvent *)
{
    QStylePainter p(this);
    QStyleOptionButton opt;
    initStyleOption(&opt);
    p.drawControl(QStyle::CE_RadioButton, opt);
}

QAbstractButton、QCheckBox、QPushButton、QRadioButton、およびQToolButtonのすべての派生クラスは、不規則なvoid paintEvent(QPaintEvent * e)インターフェースを実装する必要があります。

5オーバーライド

  • で覆われたリライト意味です
  • カバーはバーチャルキーワード実装
  • カバレッジはサブクラスは親クラスをオーバーライドします
  • オーバーライドされたときのサブクラスと親クラス関数名、仮パラメーター、および戻り値は同じです

Qtソースコードから取得したFocusOutEvent

void QAbstractButton::focusOutEvent(QFocusEvent *e)
{
    Q_D(QAbstractButton);
    if (e->reason() != Qt::PopupFocusReason)
        d->down = false;
    QWidget::focusOutEvent(e);//显式调用
}

特殊な処理はQAbstractButtonのfocusOutEventメソッドで実行され、次に親クラスのfocusOutEventが一般化された処理のために呼び出されます。

6過負荷

静的ポリモーフィズム

6.1機能

に登場同じスコープで2つの関数(同じクラス、同じファイル)の名前が同じで、仮パラメーターリストが異なる場合、それらは関数のオーバーロード関数と見なされます。翻訳者どの関数が呼び出されるかは、渡された実際のパラメーターのタイプに基づいて決定されます。機能だけに基づくことはできませんさまざまな戻り値の型オーバーロードを実現するため。

エラーの例:

Record lookup(const Account&);
bool lookup(const Account&);
Record lookup(const Account&acct);
Record lookup(const Account&);
typedef Phone Telno;
Record lookup(const Phone&);
Record lookup(const Telno&);
Record lookup(Phone);
Record lookup(const Phone);

正しい例:

Record lookup(Phone&);
Record lookup(const Phone&);
Record lookup(Name);
Record lookup(Address);

6.2オペレーター

演算子のオーバーロードにより、プログラムはクラスタイプのオペランドに異なる演算子バージョンを定義できます。オーバーロードされた演算子は、特別な名前の関数です。予約語演算子他の関数と同様に、定義する必要のある演算子シンボルの後に、オーバーロードされた演算子には戻り値タイプと仮パラメーターリストがあります。
フォーマット:

Object operator + (const Objcet&,const Object&);

組み込み型の演算子はオーバーロードできません(int型の「+」演算子はオーバーロードできません)

オーバーロードされた単項演算子がメンバー関数の場合、仮パラメーター(明示的)はありません。非メンバー関数の場合、フォーマルパラメーターがあります。同様に、オーバーロードされたバイナリ演算子によって定義されたメンバーが仮パラメーターを持っている場合、非メンバー関数として定義されています。2つの仮パラメーターがあります。

演算子は非メンバー関数として定義され、通常はオペレーティングクラスに設定する必要があります友元(友達)

7再定義

いつサブクラスは、基本クラスのメンバーと同じ名前です。時間はシールド基本クラスのメンバーへの直接アクセス。

7.1メンバー変数

class Base
{
public:
	Base():mem(0){}
protected:
int mem;
};

class Derived :public Base
{
public:
	Derived():mem(0){} //初始化Derived::mem;
	int getMem()
	{
		return mem;//返回 Derived::mem;
	}
	int getBaseMem()
	{
		return Base::mem;//返回 Base::mem;
	}
protected:
int mem;
}

7.2メンバー関数

基本クラスとサブクラスで使用同名のメンバー関数、その動作はデータと同じです。サブクラスのスコープでは、サブクラスのメンバーが基本クラスのメンバーをシールドします。関数プロトタイプが異なっていても、基本クラスのメンバーはブロックされます。

class Base
{
public:
	Base();
	int func();
};

class Derived :public Base
{
public:
	Derived();
 	int func(int);
}

Base b;
Derived d;

b.func();
d.func(2);
d.Base::func();
d.func(); //error
  • 異なるスコープ
  • 基本クラス、派生クラスでオーバーロードされた関数を再定義すると、同じ名前の仮想関数を含め、基本クラスの名前関数(つまり、他のすべてのオーバーロードされたバージョン)が自動的に非表示になります。
  • 関数の戻り値と仮パラメータリストは必要ありません

8役立つ参考資料

「C ++プログラミング思想」
「C ++入門書」
https://blog.csdn.net/lms1008611/article/details/81515727(写真)
https://www.cnblogs.com/DannyShi/p/4593735.html
https:// blog.csdn.net/haoel/article/details/1948051/

おすすめ

転載: blog.csdn.net/amwha/article/details/87520004