print - みる会図書館


検索対象: プログラミング言語C++
60件見つかりました。

1. プログラミング言語C++

4.6 関数 171 国正確な一致 . すなわち , 型変換を行わないか , 避けられない型変換 ( 配列名から ポインタ , 関数名から関数へのポインタ , T から const T への変換 ) のみを用 いた一致 . [ 2 ] 整数の昇格 ( 4.1 で定義されているもの , すなわち , char から int, short から int, 及びそれらの unsigned なものへの変換 ) や , float から double への変換を用いた一致 . [ 3 ] 標準の型変換 ( 4 で定義されているもの , 例えば , int から double, derived* から base*, unsigned int から int) を用いた一致 . [ 4 ] ューザ定義の型変換 ( 12.3 ) を用いた一致 . [ 5 ] 関数宣言における省略 ... を用いた一致 . 一致が見つかる最も高いレベルにおいて , 二つの一致が見つかったときには , 曖昧である としてその呼び出しが拒否される . 解決規則はこのように , 主に数値型についての c と C + + の詳細な規則を考慮するような詳細なものになる . 例えば , 上の print( ) の宣言を print(const char*); print ( int すべて使い , 次のように書ける : void VOid void void void void print ( double ) : print(long); print(char); h(char c ′ int print ( ′ a ′ print(49); print(O print("a"); print(c); print(i); print(s); print(f); 土′ short s, float f) / / 正確に一致 : print ( char) を起動 / / 正確に一致 : print (int ) を起動 / / 整数の昇格 : print (int ) を起動 float から double への昇格 : / / print ( double ) を起動 / / 正確に / / 正確に / / 正確に / / 正確に 一致 : 一致 : 一致 : 一致 : print ( char) を起動 print (int ) を起動 print (int ) を起動 print(const char* ) を起動

2. プログラミング言語C++

6.2 派生クラス 247 class manager employee* short public : public employee { level; 9 て oup ー manager ( char* n ′ int 1 ′ void print( ) const; int d); VOid manager : employee : cout << :print ( ) const :print( "\tlevel くく level くく 関数 print_employee( ) は , print( ) メンバ関数がその代わりをするためもはや必 要でない . 従業員のリストは employee コンストラクタ ( 扣 .2.2 ) によって作られてい それぞれの従業員はその型に応じて書き出される . 例えば : for (employee* p = list; p; void employee : : print list ( ) たので , 次のように印字することができる : p=p—>next ) p—>print ( 房 こ . Brown 12 3 4 le ▽ e1 2 こ . Smith 12 3 4 は , 次のものを出した : employee: :print list( manager 爪 ( " こ . Smith " ′ 2 ′ 12 3 4 employee e ( " J. Brown " ′ 1234 房 int main ( )

3. プログラミング言語C++

170 第 4 章関数とファイル 4.6.6 多重定義関数名 ほとんどの場合 , 異なる関数には異なる名前を与えておくのが良い . しかし , 異なる型 のオプジェクトに対して同じ仕事を実行する関数には同じ名前を与えておく方が便利なこ ともある . 異なる型に異なる演算を行うものに対して同じ名前を用いることを , 多重定義 (overloading) と呼ぶ . この技法は , c + + の基本的な演算についてすでに用いられている . すなわち , 加算には唯一の名前 + しかないが , 整数 , 浮動小数点数 , ポインタといった異 なる型を持つ値の加算に用いることができる . このアイデアは , プログラマが定義した演 算 , すなわち , 関数を処理する場合に容易に拡張できる . 例えば : void print ( int / / int を印字 / / 文字列を印字 ▽ 0 土 d print ( const char* コンバイラから見た限りでは , 同じ名前を持っ関数が共通に持っているものは , 唯一そ 語がプログラマに の名前である . おそらくそれらの関数はある意味で似ているのだが , 制約を加えたり手助けをすることはない . したがって , 多重定義された関数名は , 第一に記 法上の便利さのためものであるといえる . この便利さは , sqrt や print, open といっ た伝統的な名前を持つ関数にとっては意味論的に重要なものとなる . + , ☆ , くく ( 7.2 ) と いった演算子や , コンストラクタ ( .2.4 と 3.1 ) の場合のように , 名前が意味的に重要 となる場合には , この便利さは本質的なものとなる . 関数 f が呼ばれると , コンパイラは f という名前のどの関数を起動するのかを決定しなければならない . この決定は実引数の 型を , f と呼ばれるすべての関数の仮引数の型と比較して行われる . 引数に最も良く一致 する関数を起動し , それがなかったらコンパイル時のエラーを与えるのである . 例えば : void print ( double void print ( long ▽。土 d f( ) print( IL print ( 1 . 0 print( 1 / / print ( 10n9 ) / / print(double) / / 工ラー : 曖昧 / / print( long( 1 ) ) か print(double( 1 ) ) か ? 引数の一致についての細かい規則は 13.2 で説明してあるが , ジョンで充分であろう . これらの規則は順番に適用される : こでは , 単純化したバー

4. プログラミング言語C++

6.5 多重継承 267 class foreman : public employee { void print ( class manager : public foreman { void print ( ほとんど確実にそのつもりであったにもかかわらず , 今や foreman: :print( ) は呼び 出されない . 単純なトリックがこの問題を取り除く : class foreman : public employee { typedef employee inherited; void print ( 房 class manager : public foreman { typedef foreman inherited; void print ( void manager : : print ( ) inherited: : print ( 既存のクラスを統合する際の多重継承の役割を強調した . これは , 多重継承の , 今までに これまでの節では , 別々に開発されたソフトウェアの滑らかな統合を可能にするという , 6.5.3 仮想基底クラス を多少なりとも読みやすくするかどうかは , 趣味の問題のように思われる . が , お互いに干渉し合うことがないことを保証する . この inherited の使用が , コード スコープ規則 , 特に入れ子型に対する規則は , 結果的に生じるたくさんの inherited 型

5. プログラミング言語C++

6.2 派生クラス :print( ) const 241 VOid manager : employee : :print( / / 従業員の情報を印字 / / 管理職の情報を印字 このような名前の再利用は普通のことである . 不注意な人は : 注意されたい . manager で print( ) が再定義されているため , : : を使用しなければいけないことに VOid manager : : print ( ) const print ( / / 従業員の情報を印字 / / 管理職の情報を印字 と書くかもしれない . そして , manager: :print( ) が呼ばれたとき , 予期しない再帰 呼び出しを連続して起こすプログラムを見つけるであろう . 6.2.2 コンストラクタとデストラクタ employee(char* n, int d); public : class employee { クタが引数を必要とするならば , そうした引数が与えられなければならない . 例えば : 持つならば , そのコンストラクタが呼び出されなければならない . そしてそのコンストラ いくつかの派生クラスはコンストラクタを必要とする . 基底クラスがコンストラクタを CIass manager public : public employee { manager ( char* n, int 1 ′ int d 房

6. プログラミング言語C++

172 第 4 章関数とファイル 呼び出し print(0 ) は , 0 が int なので print(int) を起動する . print( 'a' ) は , 'a' が char なので print(char) を起動する . ( 2.5.2 ) 多重定義解決は考える関数の宣言の順序に依存せず , 関数の戻り値も考慮されないこと にラ意されたい . これらの規則が与えられると , 関係する型に応じて効率や精度が著しく異なるときでも , 最も単純なアルゴリズム ( 関数 ) が用いられることを保証することができる . 例えば : int pow( int, int double pow( double ′ double complex pow( double, complex pow( complex ′ complex pow( complex ′ complex pow( complex ′ void k( complex 2 ) complex int) ー double complex int 土 = pow( 2 ′ 2 房 double d = pow ( 2 . 0 ′ 2 complex 22 complex z3 complex 24 4.6.7 デフォルト引数 po ( 2 ′ 2 pow ( 2 po ( 2 ′ 2 / / <math . h> より / / <complex. h> より / / pow( complex ′ complex ) を起動 / / pow(complex ′ int) を起動 / / pow(double ′ complex) を起動 / / pow(double ′ double) を起動 / / pow(int,int) を起動 関数では , 最も単純な , そしてしばしば最も頻度の高い場合よりも , 一般的な場合の方 がより引数を必要とすることが多い . これは特にオプジェクトを構築する関数 ( 例えば , コンストラクタ , 5.2.4 を見られたい ) によく見られる . こういった関数は , 柔軟性のた めにオプションをいくつか提供することが多い . 整数を印字する関数を考えてみよう . 何 進法で印字するかのオプションをユーザに与えることは理にかなっているように思われる が , ほとんどのプログラムでは , 整数は 10 進整数値で印字される . void print(int valuer int base = 10 ) : void f ( ) print(31); print ( 31 ′ 10

7. プログラミング言語C++

248 第 6 章派生クラス 特定の派生クラスⅢ anager が書き表される前に employee: :print list( ) が書 かれコンバイルされたとしても , これはうまく動くであろう , ということにラ主意されたい ! 明らかに , これを実装することは , クラス employee のそれぞれのオプジェクトにある 種の型清報を記憶させておくことを意味する . 典型的な実装では , 必要とされるスペース はポインタを入れるのにちょうど充分な大きさである . このスペースは仮想関数を伴うク ラスのオプジェクトにのみ取られ , すべてのクラスオプジェクトや派生クラスのすべての オプジェクトにまで取られるわけではない . 仮想関数が宣言されたクラスに対してのみこ のオーバーヘッドは支払われ , 代わりに型フィールドの解を選んだとしても , 型フィール ドのために同等量のスペースが必要となるだろう . manager::print() でなされているようにスコープ解決演算子 : : を用いて関数 を呼び出すことは , 仮想メカニズムを使用しないことを保証している . さもなければ , manager : : print ( ) は無限の再帰を被ることになるであろう . 限定名の使用は別の望 ましい影響を持つ : もし virtual が ( 稀なことではないが ) inline でもあったとき , インライン置換は , : が呼び出しに使用されているところで使用され得る . これは , あ る仮想関数が同じオプジェクトに対して別のイ課関数を呼ぶといったような重要で特別な 場合を取り扱うための効率の良い方法をプログラマに提供する . manager: :print( ) 関数はこの例である . オプジェクトの型は manager: :print( ) の呼び出しのときに決 定されるため , その結果として起こる employee: :print( ) の呼び出しのために再び 動的に決定する必要はない . 6.3 抽象クラス 多くのクラスは , それに定義された仮想関数の穏当な実装が存在するという点で , クラ ス e Ⅲ ployee に似ている . しかし , すべてのクラスがこのパターンに従っているわけで はない . 例えば , クラス shape のようないくつかのクラスは , そのオプジェクトが存在 できないような抽象的な概念を表現する . shape はそれから派生するクラスの基底とし てのみ意味をなす . これは , その仮想関数に穏当な定義を与えることができないという事 実からわかる :

8. プログラミング言語C++

4.6 関数 print ( 31 ′ 16 房 print ( 31 ′ 2 は , 次の結果を出力する : 31 31 1 f 11111 別のやり方では , デフォルト引数を使った効果は多重定義によっても達成できる : VOid print ( int value, int base ) ー inline void print ( int value ) { print ( value, 10 ) 173 しかしながらこの場合 , その意図が単一の印字関数とその略記法であることは , 読む人に はそれほど明らかではない . デフォルト引数は関数旦言のときに型チェックされ , 呼び出されたときに評価される . デ フォルト引数は二番目以降の引数にしか提供することができない : / / 構文ェラー / / 工ラー / / 工ラー / / ok 4.6.8 不特定の数の引数 int nasty(char*=0); * と = の間のスペースがこの文脈では重要である ( * = は代入演算子 ) ことに注意されたい・ int h(int =O ′ int, char* = 0 int g(int = 0 ′ int = 0 ′ char*); int f(int ′ int = 0 ′ char* = 0 宣言される . これは。さらにいくつかの引数が来るかもしれない " ということを意味する . できない . このような関数は , 引数の宣言の並びを省略符号 (... ) で終えることにより いくつかの関数では , 呼び出し時に期待されるすべての引数の数と型を記述することが int printf(const char* 例えば : これは , printf の呼び出しには , 少なくとも一つの char * 型の引数がなければならな printf( "%d 十 %d %d\ n " ′ 2 ′ 3 ′ 5 printf( "MY name is %s %s\n" printf( " He110 ′ world\n" 房 いが , 他にはあってもなくてもよい , ということを示している . 例えば : first name ′ second name ) ー

9. プログラミング言語C++

218 第 5 章クラス #include <iostream. h> struct cl char* val; void print ( int x) cl(char* v) { val { cout くく val くく X くく′ \ n ′ 新 } メンバへのポインタは次のように宣言して使うことができる : typedef ▽ 0 土 d (cl: : *PMF 工 ) (int); int main( ) c1 z 1 ( " z 1 c1 22 ( " 22 " c 1 ☆ p = & 22 ー PMFI pf &cl: 21 . print ( 1 ( 21. *pf ) ( 2 22 ・ print(3); ( p → *pf ) ( 4 : print ー C の宣言子構文は可読陸に欠けており , それを補うために typedef を使うのが普通であ る . メンバへのポインタを特定のオプジェクトに束縛するには演算子 . * と一 > * が用いられ , こうして , 呼び出しに使うことのできる関数が生み出される . ( ) の優先頂序は . * やー > ☆ より高いので , 括弧は必要である . 多くの場合 , 関数へのポインタを使っていたようなところには , イ誤関数 ( 扣 .2.5 を見 られたい ) を使うことができる . 5.4.6 構造体と共用体 定義によると , struct は , デフォルトですべてのメンバを公開しているようなクラス である . つまり , struct s {

10. プログラミング言語C++

246 第 6 章派生クラス 6.2.5 仮想関数 仮想関数は , 各派生クラスで再定義可能な基底クラスの関数をプログラマが宣言するこ とを許すことにより , 型フィールドの解に伴う問題点を克服する . コンパイラとローダが , オプジェクトとそれに適用される関数の間の正しい対応を保証するであろう . 例えば : class employee { char* n ame ー short department ー employee* next ー static employee* list; public : employee ( char* n, int d); static void print list( 房 virtual ▽ 0 土 d print ( ) const ー キーワード virtual は , 関数 print() は異なる派生クラスに対して異なるバージョン を持ち得ること , そしてそれぞれの p て土 nt ( ) の呼び出しに対して適切な関数を見つける のはコンバイラの仕事であるということを示している . 関数の型は基底クラスで宣言され , 派生クラスで再宣言をすることはできない . イ課関数は , ( 純粋仮想関数 ( 扣 .3 を見られ たい ) として宣言されるのでなければ ) それが最初に宣言されるクラスについて定義され ていなければならない . 例えば : void employee : : print ( ) const cout くく name くく ' \t ' くく department << ' \n ' したがって , そのクラスからの派生クラスがなく , また派生クラスが特別なバージョンの 仮想関数を提供する必要のないときでさえ仮想関数を使用することができる . クラスを派 生するとき , 必要ならば適切な関数を単に提供すればよい . 例えば :