• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:継承を重ねた場合のコストはどうなるのでしょうか?)

継承を重ねた場合のコストは?

επιστημη(@episteme)の回答

回答No.1

「どんな機械語が生成されるか」という問いに対しては「コンパイラの勝手」です。 言語仕様はこの問いに対して何の答えもくれません。 プロファイルするとか、実際に吐いた機械語を吟味する以外、判断するすべはありません。 と前置きしたうえで、「それほどまでにコストを気にするアプリケーションなのか」が気になります。

LongSecret
質問者

お礼

どうも、ありがとうございます♪ やはりそうですか… >「それほどまでにコストを気にするアプリケーションなのか」が気になります。 単純に、速度の差があまりに小さくて誤差に埋もれてしまうような話なら、利便性をとるため二段の継承もしたいし、純粋仮想関数も適切に使いたいけども 速度の差が気になるようならそうも言えない という事を思っていたのですが どんな機械語が生成されるか言語仕様からは判断できないとなれば 確かに、その角度でもっと具体的に深く追求した方が良いですね。 というわけで コンストラクタ・デストラクタについては、ファイルの読み込みやアプリケーション終了などの理由から、コンストラクタ・デストラクタがぶん回されてる最中に、他のスレッドがちょっかいを出したり、何か膨大な解析をする可能性は完全に撤廃できる状況にあります。 従って、この点についてはあまりに遅くなければ問題ないということになります。 二段階継承にした時に最も上にくる基底クラスは、『インスタンス変数』としては 3つの単純な整数と、自分自身の型のポインタ(next)をさすメンバの、たった4つのメンバ変数を持ち、コンストラクタ中では初期化リストでそれらを初期化することしかしません。 これが 仮に、相当、かなり多く見積もって10万回呼ばれたとして 例えば、多く普及している平均的なの性能のXP以降ぐらいで差が1秒以内に収まるなら、全く気にならないレベルです。 意図的に余分なことをするわけはないので、それだけの差でさすがにたった10万回で1秒なんて到底かからないと見ていいでしょうか? ちなみに今ある、そこそこのファイルを読み込んだらコンストラクタが呼ばれた回数3000弱でした。 デストラクタはnextのポインタを使用して一括解放などとからんできますが、結局『継承とかかわりのある』行動としては、単に表記上virtualで一段階だったのが二段階になる、という以外全く変化はありません。 これも10万で1秒以内なら余裕です。 それ以外の仮想関数の問題については 別スレッドから可能な限り速く呼ばれる瞬間が発生するタイミングがあります。 その時に同時にメインスレッドで、仮想関数とは無関係にすさまじく膨大な演算が行われる可能性も、あるにはあります。 ただし、それは全体からみれば稀なケースです。 また、なるべくその回数を減らすようにすることも考えられます。 これは、一段の継承と二段の継承における仮想関数呼び出しの時間差が、もし発生した場合は、そのオーバーヘッドが、30万回で1秒以内ぐらいならよしとしておきます。 そんなに変わるようなことはまずないと思っていい、ですかね?

関連するQ&A

  • C++のクラスの仮想デストラクタについて

    C++のクラスの仮想デストラクタについて教えてください。 デストラクタは、クラスの名前の前にチルダを付けたものが名前になりますが、とあるクラスの継承クラスは、その親クラスとクラス名が違うので、デストラクタの名前も親クラスのものとは別になる。つまり。継承関係のあるクラスでもデストラクタはオーバーライドせず、各クラス毎に別の名前で存在する、ということになると思います。 ですので http://wisdom.sakura.ne.jp/programming/cpp/cpp31.html このページの下部にあるように、「デストラクタは、派生クラスから基本クラスへ向かって順番に呼び出される」というのもなんとなく合点が行きます。 しかし、仮想デストラクタというものがあることを知りました。 上記のようにデストラクタは継承関係のあるクラス間でも、それぞれクラス毎に作ればよいと思っていましたが、子クラスの方でオーバーライドする必要がある場合があるのでしょうか。あるとすれば、それはどんな場合なのでしょうか。 また、上記のURLでは、「C++ 言語のデストラクタはオーバーライドを行いません」と書いてあり、なんだかよく分からなくなってきました。仮想デストラクタというものが存在するのに? どなたか詳しい方いらっしゃいましたらご教示頂けると幸いです。

  • 【delphi】クラスの継承、互換性について

    //Base.pas TSituation = class(TObject) public  procedure Update;virtual;abstract;  procedure Reflect;virtual;abstract; end; //Title.pas TSceneTitle = class(TSituation) private  ・  ・  ・ public  constructor Create;  destructor Destroy;override;  procedure Update;override;  procedure Reflect;override; end; //main.pas(メインフォーム) unit main; interface uses  ・・・, Base, Title;    ・    ・    ・ var  fm_main: Tfm_main;  Situation: TSituation; --------------------------------------------------- こう、きちんとクラスの宣言も継承もしているのに、(しているはず Situation := TSceneTitle.Create; とすると互換性がないといってコンパイルエラーになります。 なにかおかしいところがあるのでしょうか。

  • 【PHP】クラスを継承した際にデータ型も継承すると

    とある有料のオンライン学習サイトをつかっています。 学習項目の流れは以下の通りです。 現在「15 型の継承について見ていこう」で躓いています。 01 オブジェクトを使ってみよう (02:56) 02 投稿に関する処理を作ろう 03 クラスでデータ型を定義しよう 04 インスタンスを作ってみよう 05 コンストラクタを使ってみよう 06 クラスを整理しておこう 07 アクセス修飾子について見ていこう 08 メソッドを介してプロパティを操作しよう 09 プロパティで型宣言をしてみよう 10 staticキーワードを使ってみよう 11 オブジェクト定数を使ってみよう 12 クラスを継承してみよう 13 子クラスで独自の実装をしていこう 14 メソッドをoverrideしてみよう 15 型の継承について見ていこう *型の継承 *型を継承するメリット この項目で記述されているソースコードは下記のとおりです。コード内のクラス、SponsoredPostは クラスPostを継承しています。よって両方のクラスともにPost型として扱えると説明があります。 ソース内のこの箇所で processPostという関数を作成し、変数$postにPost型と型付けをしています そしてforeachでPostで型付けられた$post型(クラスPostとそれを継承したクラスSponsoredPost)をひとつづつ取り出し、processPostを用いてそれぞれにshow()メソッドで表示させています。 ----------------------- <?php class Post{ protected $text; public function __construct($text){ $this->text = $text; } public function show(){ printf('%s',$this->text); } class SponsoredPost extends Post{ private $sponsor; public function __construct($text, $sponsor){ parent::__construct($text); $this->sponsor = $sponsor; } public function show(){ printf('%s by %s', $this->text, $this->sponsor); } } $posts = []; $posts[0] = new Post('hello'); $posts[1] = new Post('hello again'); $posts[2] = new SponsoredPost('iPhone','Apple'); function processPost(Post $post){ $post->show(); } foreach($posts as $post){ processPost($post); ------------- クラスを継承すると親クラスのプロパティやメソッドが子クラスに継承されるというのは理解できています。「15 型の継承について見ていこう」という項目では 『Post型の変数を受け取る関数を作って、データ型が継承されることを説明していきます。』 と解説してあります。 クラスを継承すると親クラスのプロパティやメソッドが子クラスに継承されるというのは理解できています。私の知っているデータ型(文字列型、整数型、浮動小数点数型、論理型、配列型、オブジェクト型、リソース型、NULL)は下記の2か所だけです。 show()メソッド内の、['%s']と['%s by %s']で文字列が指定されています。 したがってこの項目で説明されている 『Post型の変数を受け取る関数を作って、データ型が継承されることを説明していきます。』 とは、「クラスを継承する際にプロパティやメソッドだけでなく、データ型、ここでは(['%s']と['%s by %s'])も継承されるということが説明されているという解釈でよろしいのでしょうか? 少し混乱しています。もし私の解釈が間違っているようでしたら教えてください。 初学者です。よろしくお願いいたします。 <表示結果>

    • ベストアンサー
    • PHP
  • コンストラクタの記述について ―引数を持ったクラスを継承する場合―

    コンストラクタの記述について ―引数を持ったクラスを継承する場合― ActionScript3.0でプログラミングをしています。 クラスの継承に挑戦したのですが、うまくいきません。 コンストラクタの記述は、何か特別なものが必要なのでしょうか? ■コンストラクタに引数なし → 成功。 ■コンストラクタに引数あり → 失敗。  エラー「No default constructor found in base class <親クラスの名前>」。 ■エラーの出るソース↓ ・Main.as(コンストラクタ内抜粋)     var parent:Parent = new Parent(100);     var child:Child = new Child(200); ・Parent.as package {   import flash.display.Sprite;      public class Parent extends Sprite {     protected var str:String = "親クラスのプロパティ";     public function Parent(inNum:Number):void {       trace("親クラス, ", str, inNum);     }   } } ・Child.as package {   import Parent;   public class Child extends Parent {     public function Child(inNum:Number):void { //■エラー。       trace("子クラス, ", str, inNum);     }   } } ご存知の方、よろしくお願いします。 よろしくお願いします!

    • ベストアンサー
    • Flash
  • 継承における暗黙のデフォルトコンストラクター

    ”継承の際、スーパークラスで引数なしのコンストラクターが省略せずにきちんと記述されるなら、そのサブクラスでコンストラクターを記述しなくても、スーパークラスの引数なしのコンストラクターが受け継がれるためコンパイルエラーがおきない。”のは分かりますが”スーパークラスで引数なしのコンストラクターが省略され、かつサブクラスでコンストラクターを省略した場合”はなぜコンパイルエラーがおきるのでしょうか? 暗黙の内にスーパークラスにコンストラクターが生成され、それがサブクラスに受け継がれることは出来ないのでしょうか? 宜しく願います。

  • C++の継承と呼び出しについて

    C++について COMとMediaFoundationについて勉強中ですが、継承とオーバーライド の部分で混乱してしまったので、アドバイスをお願いします。 IUnknownクラスは、三つの純粋仮想関数を持っていて、 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)=0; virtual ULONG STDMETHODCALLTYPE AddRef(void)=0; virtual ULONG STDMETHODCALLTYPE Release(void)=0; の三つがあることがわかりました。 そのIUnknownクラスを継承したIMFAsyncCallback、 IMFAsyncCallbackをさらに継承したCPlayerクラスがあります。 CPlayerクラスの中でCPlayer::QueryInterfaceの定義・処理が記述されています。 ここで、ほかのCPlayerクラスの関数内で IUnknownのインスタンス->QueryInterface(引数) ; で呼び出された場合、 CPlayer::QueryInterfaceには飛ばないのでしょうか? 何度ブレークポイントを張ってもきていないので、 いったいどこで処理が行われているか不思議で仕方ないです。 というかIUnknownのインスタンスが作れていることすら疑問です。。。 よろしくお願いします。

  • ダイアログを継承したダイアログの作成について

    お世話になります。 今回お聞きしたいことは、 オリジナルに作成したダイアログを継承したオリジナルのダイアログを作成した際に、オリジナルに作成した基底ダイアログのダイアログ上のコントロールや、そのコントロールの位置を継承することはできますでしょうか? ということです。 何がしたいかといいますと、4つのダイアログをメインダイアログから呼び出すのですが、その4つのダイアログには共通するコントロールがあり、そのコントロールの動作もその位置も全く同じなのです。 そのため、いちいち4つのダイアログにコントロールの貼り付けや、処理を記入せずに、その共通のコントロールをもった基底ダイアログを作成して、その基底ダイアログの継承としてダイアログが作れたらなと思い、質問させて頂きました。 継承をすると、基底クラスの関数等を使うことができるというのはわかるのですが、ダイアログ上のコントロールの位置までは不可能なのかなと疑問に思いました。 ご回答を宜しくお願い致します。 開発環境は Windows CE 6.0 Visual Studio 2005 です。

  • 複数のクラスで共通した関数を使いたい場合

    C++なのですが、複数のクラスで共通して使いたい関数がある場合、親クラスに共通したい メンバ関数を作り、その子として複数のクラスを作るのが良いのでしょうか? それ以外の方法だとクラスの外でstatic宣言した関数であればクラス内で使えるようでした。 (static宣言しないとコンパイルエラーとなりました) しかし以下のサイトにあるように「共通関数継承のデメリット」があるようで推奨していないようです。 ttp://d.hatena.ne.jp/katzchang/20110216/p1 ttp://blog.jnito.com/entry/20110217/1297896355 なお、自分には上記サイトの内容は難しくて理解できませんでした。 つまり、「数のクラスで共通して使いたい関数がある」場合、上記サイトはどうすればいいと言っているのでしょうか? よろしくお願い致します。

  • 継承について

    下の質問の回答、間違ってませんか? -------------------------------------------- 親クラスのフィールドをメソッドを全て継承することになります。よって、サブクラス2は、サブクラス1とスーパークラスのメンバーを全て持つことになります。サブクラス2をインスタンス化すると、サブクラス1とスーパークラスが全てインスタンス化(コンピューターのメモリ上等に配置)されます。 ただ、可視性というものがあり、サブクラスから親クラスのメンバーを直接取り扱えない場合があります。privateや可視性修飾子無しの場合、サブクラスから直接取り扱えません。ただ、継承はされているので、インスタンスとしては存在します。例えば、 class スーパークラス{ private int abc; public int getAbc(){ return this.abc; } というクラスがあり、これを継承したサブクラスがあったとします。 サブクラスからは、privateなメンバー変数abcは直接取り扱うことができません。ただ、publicなgetAbcメソッドはサブクラスから取り扱えます。これで何が分かるかといいますと、privateなメンバーでもサブクラスに継承されるのです。単に可視性の問題で直接取り扱えないだけなのです。 また、オーバーライドされたメソッドがあったとしても、super.メソッド()で親のメソッドも呼べますので、これも継承されているのです。

  • 継承について

    みなさま、どうかお知恵を貸して下さい。 javaを勉強中で、本を読みながら試しに動かしています。 現在、実現したい動作が実現可能かどうかを調べているところです。 そのため、環境やバージョン等は決まっておりません。 むしろ、実現可能な環境やバージョンがあれば、教えてください。 実現したい機能ーーーーーーーーーーーー 親クラスAにメンバーとメソッドを定義します。 Aを継承する子クラスBを定義します。 プログラム中で、A、Bのインスタンスを生成します。 そして、A、Bを継承するCのインスタンスを生成したいのです。 Cのメンバーやメソッドは、Bと同様のものです。 この場合、BのクラスからCのようなインスタンスを作成することは、可能なのでしょうか? ・・・Cを定義していないので、おそらく不可能かと思います。 やはりこういった場合、Aを継承しているBを継承するCクラスを定義しておく必要があると考えています。 では、Cを継承するD,Dを継承するE・・・というように、いくつ必要になるかわからない場合、最大数分継承したクラスを用意すべきでしょうか。 なぜ、そうしたいかというと、組織図のようなものを作成したいのですが、組織図を構成する人数は、ユーザーの任意としたいのです。 継承したクラスを用いれば、そのまま組織図の体系を表現できる気がしました。 質問が大雑把になってしまい、申し訳ないのですが、お力を貸していただければ幸いです。

    • ベストアンサー
    • Java