クラスを使用して章XI
11.1演算子のオーバーロード
図1は、演算子をオーバーロードする、と呼ばれる演算子関数の特別な関数形の使用を必要とします。
次のようにフォーマットオペレータ機能は次のとおりです。
演算子op(引数リスト)
オペアンプ演算子opを復活させるために、新しいシンボルが虚数ではない、有効なC ++演算子でなければなりません。演算子[]()関数のオーバーロード演算子は[]、理由[]配列のインデックス動作です。
11.2計算時間:パラダイム演算子のオーバーロード
書式#include <stdio.hに> 書式#include <iostreamの> 書式#include <string.hの> 書式#include <math.h>の 書式#include <文字列> 書式#include <アルゴリズム> 書式#include <キュー> 書式#include <マップ> 長い長いLLのtypedef。 名前空間stdを使用。 #ifndefのMYTIME0_H #define MYTIME0_H 授業時間{ 民間: int型の時間。 int型分; 公衆: 時間(); 時間(INT H、INT M = 0)。 ボイドAddMin(INT M)。 無効AddHr(int型H); ボイドリセット(INT H = 0、INT、M = 0)。 CONST(時刻&T CONST)時間演算子+。 空ショー()constは、 }。 #endifの// MYTIME0_H 時間::時間(){時間=分= 0;} 時間::時間(int型H、INT M){時間= H; 分= M;} 無効時間:: AddMin(int型メートル) { 分+ = M。 時間+ =分/ 60; 分%= 60。 } 無効時間:: AddHr(int型H) { 時間+ = H; } 無効時間::リセット(int型H、int型メートル) { 時間= H; 分= M。 } 時間時間::演算子+(constの時刻&T)のconst ///オーバーロードされた加算器 { 時間の合計。 sum.minutes =分+ t.minutes。 sum.hours =時間+ t.hours + sum.minutes / 60。 sum.minutes%= 60。 合計を返します。 } 無効時間::ショー()constは { std :: coutの<<時間<< "時間、" <<分<< "分"。 std :: coutの<<てendl; } メインint型() { 時間の計画; 時間コーディング(2,40)。 時間固定(5,55)。 時間の合計。 std :: coutの<< "企画"。planning.Show(); +定着コーディング=コーディング。 std :: coutの<< "コーディング"。coding.Show(); コーディング合計=。 合計= total.operator +(固定)。 std :: coutの<< "合計"。total.Show(); }
11.2.2過負荷制限
図1は、オーバーロードされた演算子が少なくとも一方のオペランドを有していなければならない後にオペレータのオーバーロードの標準タイプとしてユーザを防止するユーザー定義型です。従って、減算演算子はない( - )は、2つの二重価値過負荷を計算し、むしろそれらの差よりもします。が、この制限は、創造性に影響を与えることになるが、それはプログラムの正常な動作を保証することができます。
演算子を使用している場合2、元オペレータの構文規則に違反することはできません。例えば、モジュロ演算子はないであろう(%
)ヘビーデューティーオペランドを使用します。同様に、演算子の優先順位を変更しません。したがって、加算演算子は2つのクラスをリロードする場合、新しいオペレータプラス同じ優先度を持つ原稿を添加します。
3、新しい演算子を定義することはできません。例えば、オペレータ**()関数は、べき乗を示し定義することができません。
4は、オペレータは次のことをオーバーロードすることはできません。
リットルのsizeofオペレータ--sizeof
L - メンバー演算子
L * - メンバポインタ演算子
L :: - スコープ解決演算子
L?: - 条件演算子
Lの型ID - RTTIオペレータ
Lのはconst_cast - キャスト演算子
リットルのdynamic_castを - キャスト演算子
リットルのreinterpret_castは - キャスト演算子
リットルはstatic_cast - キャスト演算子
11.3はじめに友人
フレンド関数、友人のクラス、メンバ関数の友人:1、3種類の友人があります。
図2に示すように、関数は、クラスの友人になるようにすることによって、そのアクセスクラスのメンバ関数と同じ機能を割り当てることができます。
3、最初にすべてのなぜ友人を必要ですか?
A:A = B *(2)A = B.operator(2)と同等である。
しかし、A = 2 * Bがない場合は?コンパイラはもうこれを理解することはできません。
(事業者のほとんどが会員か非メンバ関数によって過負荷にすることができ、覚えておいてください)非メンバ関数を必要とする、私たちはそう。非メンバ関数は、(オブジェクトを含む)オブジェクトによって呼び出されていないすべての値は、明示的なパラメータです。:このように、コンパイラは、次の式とすることができる
A * B = 2.72
と一致する以下の非メンバ関数呼び出し:
A * =演算子(B 2.75)を、
この関数のプロトタイプは以下の通りである:
時間演算子*(ダブルM、時間CONST &Tに);
非メンバ関数のオペレータ、オペレータの関数の最初のパラメータの左側の式に対応するオペランド、第二オペレータ機能に対応する右オペランド演算式を過負荷になっていますある処理動作の数、の逆の順序で元のパラメータのメンバー関数は、時間の重複値は値を乗じました。直接、少なくとも従来の非メンバ関数にアクセスすることができない、クラスのプライベートデータにアクセスすることができない非メンバ関数:しかし、それは新たな問題を引き起こしました。しかし、非メンバ関数の特別なクラスは、クラスのprivateメンバにアクセスすることができ、それらはフレンド関数と呼ばれています。
友人の作成11.3.1
1は、最初のステップは、クラス宣言でそのプロトタイプのフレンド関数を作成し、プロトタイプ宣言の前にキーワードの友人を追加することで、
友人のタイム演算子*(ダブルメートル、タイム&Tのconst); //クラスの宣言に行きます
図2に示すように、次の2点、そのプロトタイプ手段:
Lオペレータが、*()関数は、クラス宣言で悪評であり、それはメンバ関数ではないので、操作子を呼び出すために使用することができません。
演算子*()関数が、lはメンバ関数はありませんが、メンバ関数への同じアクセスを有します。
図3は、第二段階は、そう時間::修飾子を使用していない、彼はメンバ関数ではない。なお、関数定義を記述することです。また、次のように定義がある必要があり、定義でキーワードの友人を使用しないでください。
書式#include <stdio.hに> 書式#include <iostreamの> 書式#include <string.hの> 書式#include <math.h>の 書式#include <文字列> 書式#include <アルゴリズム> 書式#include <キュー> 書式#include <マップ> 長い長いLLのtypedef。 名前空間stdを使用。 #ifndefのMYTIME0_H #define MYTIME0_H 授業時間{ 民間: int型の時間。 int型分; 公衆: 時間(); 時間(INT H、INT M = 0)。 ボイドAddMin(INT M)。 無効AddHr(int型H); ボイドリセット(INT H = 0、INT、M = 0)。 CONST(時刻&T CONST)時間演算子+。 空ショー()constは、 友人タイム演算子*(int型nは、タイム&Tのconst)。 }。 #endifの// MYTIME0_H 時間::時間(){時間=分= 0;} 時間::時間(int型H、INT M){時間= H; 分= M;} 無効時間:: AddMin(int型メートル) { 分+ = M。 時間+ =分/ 60; 分%= 60。 } 無効時間:: AddHr(int型H) { 時間+ = H; } 無効時間::リセット(int型H、int型メートル) { 時間= H; 分= M。 } 時間時間::演算子+(constの時刻&T)のconst ///オーバーロードされた加算器 { 時間の合計。 sum.minutes =分+ t.minutes。 sum.hours =時間+ t.hours + sum.minutes / 60。 sum.minutes%= 60。 合計を返します。 } 無効時間::ショー()constは { std :: coutの<<時間<< "時間、" <<分<< "分"。 std :: coutの<<てendl; } 時間演算子*(タイム&Tのconst int型のn、) { タイム結果; 長い長いtotalminutes = t.hours * N * 60 + t.minutes * N。 result.hours = totalminutes / 60。 result.minutes = totalminutes%60。 結果を返します。 } メインint型() { 時間の計画; 時間コーディング(2,40)。 時間固定(5,55)。 時間の合計。 std :: coutの<< "企画"。planning.Show(); +定着コーディング=コーディング。 std :: coutの<< "コーディング"。coding.Show(); コーディング合計=。 合計= total.operator +(固定)。 std :: coutの<< "合計"。total.Show(); 合計= 2 *コーディング。 std :: coutの<< "合計"。total.Show(); }
要約:クラスのメンバ関数は、非フレンド関数、同じ権利とメンバ関数へのアクセスです。
Q:OOPに友人反しますか?
A:文があまりにもあり、片側、逆に、クラスとみなされている友人の機能拡張インターフェイスの不可欠な一部である必要があります。たとえば、概念的には、時間と時間は、二重、二重が同一である乗算を掛けました。それはむしろ、コンセプトの違いよりも、C ++構文の結果であるメンバ関数、後に、フレンド関数の前に必要とされます。フレンド関数とクラスメソッドを使用することにより、ユーザは、両方のオペレータインタフェースの同じ式を使用することができます。また、唯一のクラス宣言は、関数は、プライベートデータにアクセスすることができ、クラスの宣言はまだコントロールので、友人である機能を決めることができますことを覚えておいてください。要するに:クラスインターフェースの表現のクラスメソッドや友人ちょうど2つの異なるメカニズム。
11.3.2共通の友人:過負荷演算子<<
coutの<<時間の役割(タイプ)に、<<演算子をオーバーロードする方法1、?
2は、<<最初のバージョンオーバーロードされた
メーク利用COUT時のクラスが知っている、友人の機能を持っています。COUT <<時間ので、二つのオブジェクト、のostreamクラスオブジェクト(COUT)の一方が、<<時間をオーバーライドするメンバ関数を使用している場合、タイムオブジェクトは最初のオペランドであろう。必要があります:タイム<< COUT;これは非常に混乱しています。しかし、我々は友人の機能を使用することができ、次のようにこのようなことができます:
無効演算子<<(タイム&Tのconst OSのostream&、)
{
OSのt.hours << << << << t.minutes "分"; "時間"。
}
3、<<の第二のオーバーロードされたバージョン
はcout <<「時間」<<時間:最初のバージョンは、私たちは、この使用することはできません 。「<<てendl
?だから我々はそれを解決する方法
:基本的に同一の第1
のostream&演算子を<<(タイム&T constのOSのostream&、)
{
OS << << t.hours "時間" << << t.minutes "分";
戻りOS;
}
11.4オーバーロードされた演算子:メンバ関数または非メンバー関数として
図1は、覚えている:形状メッシュオーバーロードオペレータ関数パラメータの非メンバーのバージョンのために必要なオペランドの同じ数及び使用される演算子と少なくとも一つのメンバーのために必要なパラメータのバージョン番号、子供がオペランド暗黙的であるため呼び出し元のオブジェクトの転送を入力します。
自動変換および11.6クラスのキャスト
図1に示すように、時間T(5)。時刻t =時間(5)。
図2に示すように、伝達関数は二重に構造を変換する(その定義)を使用することができます。
伝達関数:オペレータ型名();
変換関数がクラスメソッドでなければならない
戻り型を指定しない変換
パラメータを持っていない変換関数を
以下のように、例えば、二重機能のプロトタイプに変換:
オペレータは、二重();タイプに変換するには、この点、そうこれは、戻り値の型は必要なかったです。変換関数は、クラスメソッド手段である:それは、それによって変換したい関数の値を通知する、クラスオブジェクトから呼び出される必要があります。したがって、この関数は引数を取りません。
3、まとめたもの:
C ++クラス・タイプは、次の変換を提供します。
クラス型にパラメータ値のための同じタイプの唯一のクラスのコンストラクタパラメータL。例えば、被験体はStonewt INTアサイン値であり、パラメータStonewtはINTクラスコンストラクタが自動的に呼び出され受け付けます。しかし、明示的に防止暗黙の変換コンストラクタ生明の使用、およびのみ変換を可能にします。
特別なクラスLオペレータ関数は、オブジェクト・クラスの他のタイプを変換するための伝達関数と呼ばれています。変換関数は、型名は、オブジェクトは自動的に型に変換されるでないパラメータと呼ばれるオペレータの型名()は、存在しない、クラスのメンバ、ノーリターンタイプです。クラスオブジェクトが変数または型名キャスト型名タイプに割り当てられている場合、変換関数が自動的に呼び出されます。