QWidget関係クラス図
QMainWindowはメニューバーとツールバーを備えたメインウィンドウクラスであり、QDialogはさまざまなダイアログボックスの基本クラスであり、それらはすべて子QWidgetを継承します。
C ++の継承:
オブジェクト指向プログラミングで最も重要な概念の1つは、継承です。継承により、別のクラスに基づいてクラスを定義できるため、アプリケーションの作成と保守が容易になります。このようにして、コードの再利用機能と実行時間の改善効果も実現されます。
クラスを作成するときに、新しいデータメンバーやメンバー関数を書き直す必要はありません。新しく作成したクラスが既存のクラスのメンバーを継承するように指定するだけです。この既存のクラスは基本クラスと呼ばれ、新しく作成されたクラスは派生クラスと呼ばれます。
基本クラスと派生クラス
クラスは複数のクラスから派生できます。つまり、複数の基本クラスからデータと関数を継承できます。派生クラスを定義するには、クラス派生リストを使用して基本クラスを指定します。クラス派生リストは、次の形式の1つ以上の基本クラスにちなんで名付けられています。
class derived-class: access-specifier base-class
その中で、アクセス修飾子access-specifierは、 public、protected 、privateのいずれか であり、base-classは、以前に定義された特定のクラスの名前です。access-specifierが使用されていない場合、デフォルトでprivateになります。
以下に示すように、基本クラス Shapeがあり、Rectangleがその派生クラスであるとします。
#include <iostream>
using namespace std;
// 基类
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// 派生类
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
int main(void)
{
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
アクセス制御と継承
派生クラスは、基本クラスのすべての非プライベートメンバーにアクセスできます。したがって、基本クラスのメンバーが派生クラスのメンバー関数からアクセスされたくない場合は、基本クラスでプライベートとして宣言する必要があります。
次のように、アクセス許可に基づいてさまざまなタイプのアクセスを要約できます。
アクセス | 公衆 | 保護 | 民間 |
---|---|---|---|
同階級 | はい | はい | はい |
派生クラス | はい | はい | 番号 |
外部クラス | はい | 番号 | 番号 |
派生クラスは、次の場合を除いて、すべての基本クラスメソッドを継承します。
- 基本クラスのコンストラクター、デストラクター、およびコピーコンストラクター。
- 基本クラスのオーバーロードされた演算子。
- 基本クラスのフレンド機能。
継承タイプ
クラスが基本クラスから派生している場合、基本クラスはpublic、protected、 または privateとして継承できます 。継承タイプは、上記で説明したアクセス指定子によって指定されます。
保護された 継承 や プライベート継承、通常はパブリック 継承は ほとんど使用しません 。さまざまなタイプの継承を使用する場合は、次のルールに従ってください。
- 公共の継承(パブリック):クラスが由来する場合、公開基底クラス、基本クラスのパブリック派生クラスのメンバーのパブリック基本クラスのメンバーを保護するために、派生クラスのメンバーを保護するために、基本クラスののメンバープライベートメンバーが直接クラスを派生することはできませんアクセスしますが、基本クラスのパブリックメンバーと保護されたメンバーを呼び出すことでアクセスできます。
- 保護された継承(保護された): クラスが基本クラスの保護から派生した場合、基本クラスはパブリックであり、派生クラスのメンバーの保護はメンバーを保護することです。
- プライベート継承(プライベート):クラスがプライベート基本クラスから派生した場合、基本クラスpublicおよび派生クラスのメンバーの保護はプライベートメンバーになります。
公的継承
保護された継承
プライベート継承
クラスのプライベートメンバーとプロテクトメンバーはクラス外では使用できません。クラス外で直接使用できるのはパブリックメンバーのみです。
パブリック継承の場合、基本クラスのプライベートメンバー派生クラスは使用できず、基本クラスのパブリックメンバーと保護メンバーは派生クラスで直接使用できます。継承(派生クラスの対応するパブリックメンバーと保護メンバーになります)は、パブリックメンバーのみが派生クラスに含まれます。外で直接使用できます。
継承を保護する場合、基本クラスのプライベートメンバーは引き続きプライベートです。基本クラスのパブリックメンバーと保護メンバーは派生クラスの保護メンバーになります。現時点では、元の基本クラスのパブリックメンバーを派生クラスの外部で直接使用することはできません。
プライベート継承では、基本クラスのプライベートメンバーは引き続きプライベートです。基本クラスのパブリックメンバーと保護されたメンバーは、派生クラスのプライベートメンバーになります。
例えば。
クラスA
{{
公衆:
int m_nTelNum;
保護:
int m_nAge;
民間:
int m_nMoney;
};
クラスB:パブリックA
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum;
}
void SetAge(int nAge)
{{
m_nAge = nAge;
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //基本クラスのプライベートメンバーを使用できないため、ここでエラーが発生します。
}
};
B objB; //タイプBobjBのオブジェクトを作成します
objB.m_nTelNum = 123456; //はい
objB.m_nAge = 30; //エラー。パブリック継承での基本クラスの保護は、派生クラスで保護されます。
objB.m_nMoney = 100; //さらに間違って、派生クラスで直接使用することはできません。クラス外で使用することはできません。
クラスC:保護されたA
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum;
}
void SetAge(int nAge)
{{
m_nAge = nAge;
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //これは基本クラスのプライベートメンバーであり、使用できないため、ここでエラーが発生します。
}
};
C objC; //クラスCobjCのオブジェクトを作成します
objC.m_nTelNum = 123456; //これとpublicの違いに注意してください。ここにエラーがあり、m_nTelNumはクラスCの保護されたメンバーになりました。
objC.m_nAge = 30; //エラー。保護された継承の基本クラスの保護は、パブリックと同じ派生クラスで保護されます。
objC.m_nMoney = 100; //さらに間違って、派生クラスで直接使用することはできません。クラス外で使用することはできません。
クラスD:プライベートA
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum;
}
void SetAge(int nAge)
{{
m_nAge = nAge;
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //これは基本クラスのプライベートメンバーであり、使用できないため、ここでエラーが発生します。
}
};
D objD; //クラスDobjDのオブジェクトを作成します
objD.m_nTelNum = 123456; //エラー、m_nTelNumがクラスDのプライベートメンバーになりました
objD.m_nAge = 30; //エラー。プライベート継承での基本クラスの保護は、派生クラスではプライベートです。
objD.m_nMoney = 100; //さらに間違って、派生クラスで直接使用することはできません。クラス外で使用することはできません。
例から判断すると、3種類の継承は、クラス外で参照されている場合にのみ、派生クラス内の参照と違いがないように見えます。現在、パブリック継承と保護継承の間に違いはありません。
別の例を見てみましょう。
クラスE:パブリックB
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum; //はい、これはBのパブリックメンバーであるため
}
void SetAge(int nAge)
{{
m_nAge = nAge; //はい、これはBの保護されたメンバーであるため、Eの保護されたメンバーになります
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //これは絶対に不可能です!
}
};
E objE; //
objE.m_nTelNum = 123456; //はい
//他の2つは使用できません。
クラスF:パブリックC
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum; //はい、これはCの保護されたメンバーであるため、ここではパブリック継承とは異なりますが、表示されていません。
}
void SetAge(int nAge)
{{
m_nAge = nAge; //はい、これはCの保護されたメンバーであるため、Eの保護されたメンバーになります
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //これは絶対に不可能です!
}
};
F objF;
objF.m_nTel = 123456; //これはFの保護されたメンバーであるため、エラーです。クラスEとの違いに注意してください。
クラスG:パブリックD
{{
void SetTelNum(int nTelNum)
{{
m_nTelNum = nTelNum; //いいえ、これはDのプライベートメンバーであるため、ここでの違いに注意してください
}
void SetAge(int nAge)
{{
m_nAge = nAge; //いいえ、これはDのプライベートメンバーであるため、違いに注意してください
}
void SetMoney(int nMoney)
{{
m_nMoney = nMoney; //これは絶対に不可能です!
}
};
// Gには、クラス外で参照できる継承されたメンバーがありません!
//これらの継承方法を理解するのは困難です。最善の方法は、試すコードをさらに作成することです。
ラベルはヒープ上に構築され、アプリはスタック上に構築されます。これは、アプリの後にラベルが破棄されることを意味します。つまり、ラベルのライフサイクルはアプリのライフサイクルよりも長くなります。これはQtプログラミングのタブーです。