【C++ベース】イントラネット、静的メンバー、友元について
5856 ワード
インライン関数
インライン関数とは?
inlineで修飾された関数をインライン関数と呼びます.例:
MAX関数は2つの整数変数aとbの大きさを比較する関数であり,inlineで修飾されたものをインライン関数と呼ぶ.
では、インライン関数はどのような役割を果たしますか?
C++コンパイラはコードをコンパイルするとき,インライン関数に遭遇するとコードを展開し,関数スタックのオーバーヘッドがない.
マクロ関数に似ているように見えますか?
では、マクロ関数とインライン関数の違いは何でしょうか.
Cでは、マクロ関数が少し多く、マクロ関数は関数スタックのオーバーヘッドを回避し、実行効率を向上させることができますが、プリプロセッサはマクロコードを処理する際に、避けられない境界効果が発生する可能性があります.例えば、次のようにします.
上のマクロコードは、次の文で次のように展開されます.
+オペレータの優先度は?オペレータなので、このマクロはいつも私たちが望んでいるほどではありません.
このように変更すると、かっこを付けると、一般的には問題ありませんが、次の場合は問題が発生します.
上記の場合iは2回加算されているので、問題も発生します
マクロのもう一つの欠点は、そのデバッグ不可性であり、インライン関数はデバッグ可能であり、コンパイル段階でコードを展開することもありますが、debug段階では展開されず、普通の関数と同じようにreleaseバージョンでインラインが生成されます.
マクロはコードの読み取りが悪くなり、インライン関数は
C++にとって、マクロのもう一つの欠点は、プライベートクラスのメンバーが操作できないことです.
したがって、C++では、インライン関数はマクロコードの利点があり、マクロコードの欠点もないので、できるだけインラインでマクロコードの代わりにする
インライン関数については、次の点に注意してください.
・inlineは、呼び出し関数のオーバーヘッドを省く空間で時間を変える方法である.したがって、コードが長いか、ループ/再帰的な関数はインラインを使用するのに適していません.
・nlineはコンパイラにとってただの提案であり、コンパイラは自動的に最適化され、inlineと定義された関数内に循環/再帰などがある場合、コンパイラは最適化時にインラインを無視する
・inlineは関数定義を一緒にしないとインライン関数になりません.inlineを宣言する前に置くだけでは役に立たない
・クラス内で定義されたメンバー関数はデフォルトでインライン関数として定義されます
Google C++コード仕様では、より明確かつ詳細に規定されています.
インライン関数:Tip:関数が10行以下の場合にのみインライン関数として定義.
定義:関数がインライン関数として宣言されると、コンパイラは通常の関数呼び出しメカニズムではなくインライン展開します.
利点:関数体が小さい場合、コードの実行効率を向上させることができます.
欠点:インラインの乱用はコードの肥大化を招き、運行速度を遅くする.
結論:1つの比較的合理的な経験準則は、10行を超える関数をインラインしないでください.関数の内部に循環と再帰の関数があってもインラインを使用しないでください.
クラスの静的メンバー
クラスではstaticによって修飾されたメンバーを静的メンバーと呼び、クラスの静的メンバーはクラスのすべてのオブジェクトで共有されます.
上の日付クラスでは、日付クラスが作成されたオブジェクトの回数を統計したいので、静的メンバー変数countで統計します.
静的メンバー変数には銀行のthisポインタがないので、呼び出すときはドメイン名::を呼び出します.
静的メンバー変数はクラスで宣言されるだけなので、クラスの外で定義して初期化します.
まとめ:
・静的メンバー変数static変数による修飾
・静的メンバー変数は、クラス外でメモリ領域を個別に割り当てる必要がある
・静的メンバー変数の宣言期間は、いずれのオブジェクトにも依存しない
・公有静的メンバー変数にクラス名で直接アクセス可能
・すべてのオブジェクトが静的メンバー変数を共有する
・共有静的メンバー変数にオブジェクトから直接アクセス可能
・静的メンバー変数がプログラム内でグローバルデータ領域に存在する
友元
C++はクラスオブジェクトのプライベート部分へのアクセスを制御しますが、特定のプログラミング問題に適していないほど厳格な制御を行う場合があります.この場合、C++は別の形式のアクセス権を提供します.友元
友元は3種類に分けられ、あります.
1.友元関数
関数をクラスの友元とし、その関数にクラスのメンバー関数と同じアクセス権を与えることができます.
クラスに二元演算子を再ロードする場合、友元が必要になることが多いのはなぜですか.くりを一つあげる
Timeオブジェクトに実数を乗じた場合、AとBはいずれもTimeオブジェクトを表します.
A = B * 2.75;
この式は、次のメンバー関数に変換されて呼び出されます.
A = B.operator*(2.75);
しかし、次の文は?
A = 2.75 * B;
最初の式はメンバー関数に対応しないため、コンパイラはメンバー関数呼び出しを使用して式を置き換えることはできません.
この問題を解決するには、*番号の右側にオブジェクトをマージするか、非メンバー関数を使用して解決するか、非メンバー関数はオブジェクトによって呼び出されないため、最初のパラメータはthisポインタではありません.呼び出すと、A=operator*(2.75*B)になります.
ただし、通常の非メンバー関数ではクラスのプライベートデータに直接アクセスできないため、友元関数があります.
友元関数の作成
友元関数を作成する最初のステップは、関数のプロトタイプをクラスの宣言に配置し、プロトタイプ宣言の前にキーワードfriendを追加することです.
・友元関数operator*()はクラス宣言で宣言されていますが、メンバー関数ではありません
・メンバー関数ではありませんが、メンバー関数と同じアクセス権
2つ目のステップは、関数を定義することです.メンバー関数ではありません.Time::限定子を使用しないでください.friendキーワードを追加する必要もありません.次のように定義します.
よく使用されるFriend:再ロード<
クラスでshow()関数を定義してオブジェクトを印刷しました
これにより、cout<<クラス名;
使用できるように見えます<
問題ないように見えますが、呼び出し時:cout<
インライン関数とは?
inlineで修飾された関数をインライン関数と呼びます.例:
inline int MAX(int a, int b) {
return a > b ? a : b;
}
MAX関数は2つの整数変数aとbの大きさを比較する関数であり,inlineで修飾されたものをインライン関数と呼ぶ.
では、インライン関数はどのような役割を果たしますか?
C++コンパイラはコードをコンパイルするとき,インライン関数に遭遇するとコードを展開し,関数スタックのオーバーヘッドがない.
マクロ関数に似ているように見えますか?
では、マクロ関数とインライン関数の違いは何でしょうか.
Cでは、マクロ関数が少し多く、マクロ関数は関数スタックのオーバーヘッドを回避し、実行効率を向上させることができますが、プリプロセッサはマクロコードを処理する際に、避けられない境界効果が発生する可能性があります.例えば、次のようにします.
#define MAX(a, b) (a) > (b) ? (a) : (b)
上のマクロコードは、次の文で次のように展開されます.
result = MAX(i, j) + 2;
result = (i) > (j) ? (i) : (j) + 2;
+オペレータの優先度は?オペレータなので、このマクロはいつも私たちが望んでいるほどではありません.
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
このように変更すると、かっこを付けると、一般的には問題ありませんが、次の場合は問題が発生します.
result = MAX2(i++, j);
result = (i++) > (j) ? (i++) : (j);
上記の場合iは2回加算されているので、問題も発生します
マクロのもう一つの欠点は、そのデバッグ不可性であり、インライン関数はデバッグ可能であり、コンパイル段階でコードを展開することもありますが、debug段階では展開されず、普通の関数と同じようにreleaseバージョンでインラインが生成されます.
マクロはコードの読み取りが悪くなり、インライン関数は
C++にとって、マクロのもう一つの欠点は、プライベートクラスのメンバーが操作できないことです.
したがって、C++では、インライン関数はマクロコードの利点があり、マクロコードの欠点もないので、できるだけインラインでマクロコードの代わりにする
インライン関数については、次の点に注意してください.
・inlineは、呼び出し関数のオーバーヘッドを省く空間で時間を変える方法である.したがって、コードが長いか、ループ/再帰的な関数はインラインを使用するのに適していません.
・nlineはコンパイラにとってただの提案であり、コンパイラは自動的に最適化され、inlineと定義された関数内に循環/再帰などがある場合、コンパイラは最適化時にインラインを無視する
・inlineは関数定義を一緒にしないとインライン関数になりません.inlineを宣言する前に置くだけでは役に立たない
・クラス内で定義されたメンバー関数はデフォルトでインライン関数として定義されます
Google C++コード仕様では、より明確かつ詳細に規定されています.
インライン関数:Tip:関数が10行以下の場合にのみインライン関数として定義.
定義:関数がインライン関数として宣言されると、コンパイラは通常の関数呼び出しメカニズムではなくインライン展開します.
利点:関数体が小さい場合、コードの実行効率を向上させることができます.
欠点:インラインの乱用はコードの肥大化を招き、運行速度を遅くする.
結論:1つの比較的合理的な経験準則は、10行を超える関数をインラインしないでください.関数の内部に循環と再帰の関数があってもインラインを使用しないでください.
クラスの静的メンバー
クラスではstaticによって修飾されたメンバーを静的メンバーと呼び、クラスの静的メンバーはクラスのすべてのオブジェクトで共有されます.
class Date{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year),
_month(month),
_day(day){
//
_year = year;
_month = month;
_day = day;
// , count++
++count;
}
inline void Display() const {
cout << "year:" << _year << endl;
cout << "month" << _month << endl;
cout << "day" << _day << endl;
}
static void PrintCount() {
cout << count << endl;
}
private:
int _year;
int _month;
int _day;
private:
//
static int count;
};
上の日付クラスでは、日付クラスが作成されたオブジェクトの回数を統計したいので、静的メンバー変数countで統計します.
静的メンバー変数には銀行のthisポインタがないので、呼び出すときはドメイン名::を呼び出します.
静的メンバー変数はクラスで宣言されるだけなので、クラスの外で定義して初期化します.
int Date::count = 0;
まとめ:
・静的メンバー変数static変数による修飾
・静的メンバー変数は、クラス外でメモリ領域を個別に割り当てる必要がある
・静的メンバー変数の宣言期間は、いずれのオブジェクトにも依存しない
・公有静的メンバー変数にクラス名で直接アクセス可能
・すべてのオブジェクトが静的メンバー変数を共有する
・共有静的メンバー変数にオブジェクトから直接アクセス可能
・静的メンバー変数がプログラム内でグローバルデータ領域に存在する
友元
C++はクラスオブジェクトのプライベート部分へのアクセスを制御しますが、特定のプログラミング問題に適していないほど厳格な制御を行う場合があります.この場合、C++は別の形式のアクセス権を提供します.友元
友元は3種類に分けられ、あります.
1.友元関数
関数をクラスの友元とし、その関数にクラスのメンバー関数と同じアクセス権を与えることができます.
クラスに二元演算子を再ロードする場合、友元が必要になることが多いのはなぜですか.くりを一つあげる
Timeオブジェクトに実数を乗じた場合、AとBはいずれもTimeオブジェクトを表します.
A = B * 2.75;
この式は、次のメンバー関数に変換されて呼び出されます.
A = B.operator*(2.75);
しかし、次の文は?
A = 2.75 * B;
最初の式はメンバー関数に対応しないため、コンパイラはメンバー関数呼び出しを使用して式を置き換えることはできません.
この問題を解決するには、*番号の右側にオブジェクトをマージするか、非メンバー関数を使用して解決するか、非メンバー関数はオブジェクトによって呼び出されないため、最初のパラメータはthisポインタではありません.呼び出すと、A=operator*(2.75*B)になります.
ただし、通常の非メンバー関数ではクラスのプライベートデータに直接アクセスできないため、友元関数があります.
友元関数の作成
友元関数を作成する最初のステップは、関数のプロトタイプをクラスの宣言に配置し、プロトタイプ宣言の前にキーワードfriendを追加することです.
friend Time operator*(double m, const Time & t);
・友元関数operator*()はクラス宣言で宣言されていますが、メンバー関数ではありません
・メンバー関数ではありませんが、メンバー関数と同じアクセス権
2つ目のステップは、関数を定義することです.メンバー関数ではありません.Time::限定子を使用しないでください.friendキーワードを追加する必要もありません.次のように定義します.
Time operator*(doublt m, const Time& t) {
//TODO
}
よく使用されるFriend:再ロード<
クラスでshow()関数を定義してオブジェクトを印刷しました
これにより、cout<<クラス名;
使用できるように見えます<
//<
問題ないように見えますが、呼び出し時:cout<