shape - みる会図書館


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

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

249 class shape public : virtual ▽土て tual 63 抽象クラス void rotate ( int ) { error ( " shape : : rotate " ) ▽ 0 土 d draw( ) { error ( " shape : : draw" ) こういう特定されていない種類の形状を作ろうとすることは , 馬鹿げているが合法である : shape s ー / / 馬鹿げている : 。形のない形状 " s に対するすべての演算はエラーになるため , 馬鹿げている . より良い代わりの方法は , クラス shape のイ廨課関数を純粋仮想関数 (pure virtual func- tion) として宣言することである . 仮想関数は初期設定子 = 0 によって純粋仮想関数に なる : class shape public : virtual virtual ▽ 0 土 d void rotate ( int ) draw( ) / / 純粋仮想関数 / / 純粋仮想関数 ーっ又はそれ以上の純粋仮想関数を伴うクラスは抽象クラス (abstract class) であり , 抽 象クラスのオプジェクトは作ることができない : shape s ー / / 工ラー : 抽象クラス shape の変数 抽象クラスは他のクラスの基底としてのみイ吏用できる . 例えば : class circle : public shape { int radius ー public : void rotate (int ) { } / / ok : void draw( circle(point p ′ int て shape : shape : : rotate を上書きする :draw を上書きする

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

shape x; shape* p; shape f( void g(shape); shape& h(shape& ) : リファレンスマニュアル r.. 10.4 スコープ規則の要約 抽象クラスのオプジェクト 733 工ラー ok ユ - ラー 工ラー ok 純粋仮想関数は , 純粋仮想関数として継承される . 例えば , class ab circle : public shape { int radius ー public : void rotate ( int ) { } / / ab circle: :draw( ) は純粋イ反想 shape::draw() は純粋イ反想関数であるから , ab circle::draw() もデフォルトで 純粋仮想である . 代替の宣言 class circle : public shape { int radius ー public : void rotate ( int ) { } 参照されたい . 宣言位置の考えは , ( 3.2 ) において議論する . この節では , 字句解析上のスコープだけを議論する . リンケージ問題の説明は , 3.3 を される文脈で , 文法がそのような名前を許すところであれば , どこでも一様に適用される . ( 卯記手翹襯 es ( 阯 7.1.3 ) や c - 翹襯 es ( 9.1 ) を含む ) に対して , 特定の規則で議論 こで , c + + プログラムのスコープ規則を要約できる . これらの規則は , すべての名前 r. 10.4 スコープ規則の要約 た場合の結果は , 末定義である . が作成しようとしているオプジェクトに対して , 純粋イ誤関数を直接又は間接に呼び出し 抽象クラスのコンストラクタからメンバ関数を呼び出せる . このようなコンストラクタ 必ずどこかで与えられる必要がある . では , クラス circle は非仮想になるだろう . ゆえに , circle: :draw( ) の定義は , void draw( 房 / / どこかで定義される必要がある

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

6.4 完全なプログラム / / すべての形状を描く 259 注意されたい・ ▽ 0 土 d shape refresh( ) screen Clear( ) ー for (shape* p = shape: :list; p; screen refresh( 房 ある : void stack(shape* p ′ const point n = q—>north ( ) : point s = p—>south ( 房 ▽ 0 土 d shape refresh( 最後に , 純粋なユーティリティ関数を示す . それは , 一方の形状の south( ) をもう一方 の north() の真上にすることによって , 一方をもう一方の上に積み重ねるというもので べての形状を描き直す . これはどういう種類の形状を描いているかを考えていないことに 再描画関数は , 我々の素朴な画面をうまく処理するために必要である . それは , 単純にす void stack(shape* p, const shape* q); / / p を q の上に置く p=p—>next ) p—>draw( shape* q); p—>move ( n . x—s . x ′ n ・ y— s ・ y 十 1 / / p を q の上に置く ムこのライプラリはソフトウェアを売るある会社によって所有されていると見なされ ており , 形状の定義を含んだヘッダファイルとコンバイルされた関数定義だけが売られて いる , と想像してみよう . それでも , 新しい形状を定義し , 独自の形状に対して汎用の関 数を利用することは可能である . 6.43 アプリケーションプログラム アプリケーションプログラムは非常に単純である . 新しい形状 myshape ( 印字された とき , 顔のようにちょっと見える ) が定義される . それから , 帽子をかぶったそういう顔 を描く主プログラムが書かれる . まず , myshape の宣言をここに示す :

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

612 第 13 章ライプラリの設計 template く class T> Vector { int sz; public : vector ( int s ) { p new T[sz=s] ユーザが Shape オプジェクトそのものではなく Shape へのポインタを挿入すると仮定 すると , これは両方の選択肢を提供している . Vector<Shape*> vsp(200); Vector<Shape> vs ( 200 / / 良い / / コンバイル時工ラー 幸いにも , 抽象基底クラス Shape のオプジェクトの配列を作成しようとするとコンバイ ラがそれを捕えてくれる . しかしながら , ポインタを用いるということは , 誰がコンテナに保存されているオプジェ クトの削除に責任を持つかについて , ライプラリとユーザが合意していなければならない ことを意味する . 例えば : void f ( ) / / メモリ管理機能の混乱した使用 Vector<Shape*> v( 10 Circ1e* cp = new Circ1e; v [ 0 ] new Triang1e ー v [ 1 ] Square s ー ▽ [ 2 ] delete cp; / / 包含されるポインタによって指されている / / オプジェクトを削除しない .4.3 の▽ ecto ての実装が与えられたとすると , TriangIe は今や ( ガーベジコレクタ を取り入れていないと仮定すると , 永遠に ) 参照されないままである . メモリ管理では一 貫性がすべてである . 例えば :

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

255 void screen clear ( ) { screen_init ( ) void screen refresh( ) for (int y=YMAX—1; 0<=y; y——) { fO て (int x=O; x<XMAX; x 十十 ) cout くく screen[x] [y]; cout くく′ \ n ′ 6.4 完全なプログラム / / 上から下へ / / 左から右へ 今や , これらの定義は , 変更できないライプラリの中にあって , のみ利用可能であると想像することができる . 6.4.2 形状ライプラリ 形状の一般的な概念を定義しなければならない . この定義は , それがすべての特定の形 コンパイラの出力として て , どの形状も , クラス shape により提供されるインタフェースを通じて排他的に操作 状 ( 例えば , 円や正方形 ) により ( 基底クラス shape として ) 共有されるように , そし shape* next ー static shape* list; struct shape { されるように , なされなければならない : shape ( ) virtual virtual virtual ▽土て tua1 ▽土て tua1 virtual virtual virtual virtual virtual list; list { next this point point point point point point point point north ( ) const south ( ) const east( ) const west( ) const neast( ) seast( ) nwest( ) swest( ) void draw( ) VOid move ( int ′ const const const const int )

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

6.4 完全なプログラム 261 ▽ 0 土 d myshape : : draw( ) rectangle : : draw( int a (swest( ) ・ x + neast( ) ・ x ) / int b (swest( ) ・ y + neast( ) ・ y ) / screen_init ( ) ー int main( ) 最終的に我々は , いくつかの形状を作り , それらを動かすことができる : mouth—>move ( a, b r_eye—>move ( a ′ b 1 eye—>move ( a ′ b rectangle : :move ( a,b 房 void myshape : :move ( int a, mouth を動かすことによって動く : myshape は , 基本となる rectangle put_point ( point ( b ) , 及び二次的なオプジェクト 1 eye, int b ) r_eye, shape* pl new rectang1e(point(O ′ 0 ) ′ point( 10 ′ 10 ) 再び注意されたい . 分コンパイルされた ) はるか後に定義された型のオプジェクトをどのように操作するかに shape_refresh( ) や stack( ) のような関数が , これらの関数が書かれた ( そして多 return 0 ー screen destroy( ) ー shape refresh( stack()l ′ P2房 stack()2 ′ p3 p3 ー > 爪 0 ▽ e ( ー 10 ′ー 10 房 shape refresh( new myshape ( point ( 15 ′ 10 ) ′ po 土 nt ( 27 ′ 18 ) 房 shape* p3 shape* p2 new 1 土 ne ( po 土 nt ( 0 ′ 15 ) ′ 17 房

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

8.3 。。薄切りにする " ことを拒むであろう : リストテンプレート 345 void g2 (S1ist<shape>& 01 土 st ′ const circle& c) クラステンプレートへの引数としてリファレンスを使用してはならない . 例えば : / / 良い plist. insert(&grin); void g3(S1ist<shape*>& plist, const smiley& grin) 薄切りの問題を避けるためにはポインタを使用しなければならない : / / 作成しようとした 01土St ・ insert(c); / / 工ラー : 抽象クラスのオプジェクトを void g4(S1ist<shape&>& て1土St . insert(grin) ー を引き起こす . この場合 S1ist: :insert(T&) ー を展開すると , 違法な宣言 S1ist: :insert(shape&&) ー rlist, const smiley& grin) / / 工ラー : 生成されたコードはリファレンス / / へのリファレンスを含む (Shape&&) このように用いられるリファレンスは , テンプレートが展開されたときにしばしば型工ラー いアイデアである : ポインタのリストは非常に便利であるため , それらに特定の名前を付けておくことは良 つことはできない . になる . リファレンスはオプジェクトではないため , リファレンスへのリファレンスを持

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

368 第 8 章テンプレート 純な間違いもある . 共通のテンプレートから生成された二つの型は , それらのテンプレート引数が同一でな い限り , 異なるものであり , また継承関係は持たない . 例えば : Vector<int> v3 ー Vector<short> v2 ー vector<int> vl ー class Vector { / ☆ template く class T> 黙の変換が存在するという事実は , vector<short> から vector<int> への暗黙の こで , vl と v3 は同じ型を持ち , v2 は全く異なる型を持つ . short から int への暗 これは , int[ ] と short[ ] の間に組み込みの変換が存在しないことから , 予期するこ v2 = v3 ー / / ェラー : 型の不一致 変換があるということを意味しない : Vector<circle*> V6 : Vector く shape*> v5 ー Vector<circle*> V4 ー class circle : public shape { / ☆ 同様に とができるのではないかと思うのだが . ンタではなく引数の型のオプジェクトを含んでいるかもしれない . さらに , もしそのよう 継承関係を仮定できないものであるからである . 例えば , 生成されたクラスは単なるポイ その理由は , 一般にクラステンプレートから生成されたーっのクラスの構造 ( 表現 ) は , ▽ 5 = ▽ 6 ー / / ェラー : 型の不一致 黙の変換があるということを意味しない から vector く shape> へ , . 及び vector<circle*> から vector<shape*> への暗 び circle* から shape * への暗黙の変換が存在するという事実は , vector<circle> こで , v4 と v6 は同じ型を持ち , ▽ 5 は全く異なる型を持つ . circle から shape へ , 及

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

256 第 6 章派生クラス 考え方としては , 形状は , move( ) によって位置が決められ , draw( ) によって画面上 に置かれる . コンパスの方位にちなんで名付けられた , 接点 (contactpoint) という概念 を使用して , 相対的に形状の位置を決めることもできる . それぞれの特定の形状は , それ 自身でこれらの点の意味を定義しどのように描かれるかを定義する . コンストラクタ shape: :shape( ) は , その形状をリスト shape: :list に追カロする . このリストは , それぞれの shape オプジェクトの next メンバを用いて保守される . ただの shape オ プジェクトを作成することは意味をなさないため , クラス shape は抽象クラスにされる . 線は , 二つの占又は一つの点と整数 , のどちらかから構築される . 後者は , 整数によっ て指定される長さを持っ水平線を描く . 整数の符号は , その点が左 , 又は右の終点かどう かを示す : class line : public shape { " w " から " e " への線 . north ( ) は。。中央の上へ最も北の点と同じだけ北 " と定義されている . point public : point point point point point point point point W ′ e ー north ( ) const return point((w. x 十 e . x)/2,e. y<w. y?w ・ y:e ・ y); } south( ) const return point((w. x 十 e . x)/2 ′ e . Yく曾 . y?e ・ y:w ・ y); } swest( ) const; nwest( ) const; seast( ) const; neast( ) const; west( ) const; east( ) const; ▽ 0 土 d move ( int a, int b ) { w. x 十 = a ー w ・ y 十 = b ー void draw( ) { line(point a ′ line(point a ′ put_line (w point b) { int 1 ) { w e . x 十 = a ー e . y 十 = point ( a ・ x 十 1 ー 1 ′ a ・ y );

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

48 第 1 章 C + + ひとめぐり るのか ? C + + は静的な型チェックに大きく依存しているので , この式は , 関数 rotate( ) が宣言されていて初めて意味を持っことになる . さらに , p->rotate という記法は , p があるクラスのオプジェクトへのポインタでなければならす , て otate がそのクラスのメ ンバでなければならないことを示している . このチェックーすべての静的な型チェックに ついてなのだが一の目的は , 実行前に決定できる限りにおいてプログラムに型の使用の 矛盾がないということを保証することであり , 言い換えれば , かなりの部類のエラーがプ ログラムの実行中に起こらないことを保証することである . したがって , 次に示すように .2.5 で示したクラスの宣言 class shape { public : virtual void rotate ( int が使えなければならず , また , p は のように旦言されていなければならない . こで T は , shape 型 , 又は shape から派生し たクラスの名前である . p の指すオプジェクトのクラスが実祭に関数て otate ( ) を持ってお り , その関数は土 nt 型の引数を受理するということがわかる . これは , p->rotate()5 ) という式が正しいものであることを意味している . shape: :rotate( ) は仮想関数として宣言してあったので , 仮想関数呼び出しを使 わなければならない . その呼び出しメカニズムは , オプジェクトの中を探し , どの関数 rotate( ) を呼び出すべきかを決めるためにコンバイラが置いた情報を見つけ出す . その 関数がいったん見つかれば , 例えば c 土 rcle : :rotate であるとすると , 上述したメカ ニズムを使ってそれを呼び出せる . よくある実装技法は , コンパイラが名前 r 。 tate を , 関数へのポインタから成る表の中へのインデックスに変換することである . shape オプ ジェクトは , 次のように見えるだろう .