1

警告:これは、私がこの方法で解決することはおそらくないだろう何かについてのばかげた質問であることに注意してください。したがって、矛盾したタイトル。しかし、非常に大規模なシステムで実行したコードに似たものを実際に見たので、興味をそそられました。:)

単純化されたクラスがあるとしましょう:

class Foo
{
  void a();
  virtual void b();
}

それから別のクラス

class Bar : public Foo
{
  void a();
}

プログラムの一般的な部分がこれらすべてのクラスを type の基本クラスとして処理する場合Foo、どのようにしてa内の「正しい」バージョンの関数を呼び出すのが最善bでしょうか? オブジェクトが型である可能性があるためBar。また、従来の理由により、既存のコードを変更して、基本クラスを関数仮想にすることができなかったとします。

私がしたことaは、基本クラスで仮想化し、そのオプションがあったので実装bすることでした。Barしかし、議論のために、これは不可能または許可されていなかったとしましょう。このようなものを使用して回避策を実装するのは、どれほど「間違っている」でしょうか。

void b() {
  ...

  Bar* dabar;
  if((dabar = dynamic_cast<Bar*>(this)) != NULL) {
    dabar->a();
  }
  else {
    a();
  }
}

私が言ったように、これは基本クラスを扱い、子クラスの関数を呼び出したい場合であることに注意してください。その逆ではありません。

4

3 に答える 3

2

基本クラスで関数を仮想化する可能性がある場合、これは明らかに設計上の欠陥であるため、コードを変更するために別の会社に電話するオーバーヘッドを含めて、行くべき道です。

何らかの理由でこの可能性がない場合でも、Bar から派生させたい場合を除いて、コードは機能します。Bar* があり、その上で "a" を呼び出すとどうなると思いますか。

お気に入り:

Chair : public Bar {...}

Bar *bar = new Chair;
bar->a();
// what the heck?

もちろん、dynamic_cast はパフォーマンスに深刻な悪影響を及ぼします。

きれいなコードを書く、表現したいことを書く、トリックは使わない!

于 2012-07-03T09:03:40.477 に答える
1

このようなものを使用して回避策を実装するのは、どれほど「間違っている」でしょうか。

void b() {
  ...

  Bar* dabar;
  if((dabar = dynamic_cast<Bar*>(this)) != NULL) {
    dabar->a();
  }
  else {
    a();
  }
}

それはやり過ぎでしょう。仮想関数で a() を呼び出すだけでうまくいきます。

#include <iostream>

class Base
{
public:
    virtual int tryit()
    {
        return foo();
    }
private:
    int foo(){ return 1; }
};

class Derived: public Base
{
public:
    virtual int tryit()
    {
        return foo();
    }

private:
    int foo(){ return 2; }
};

int main()
{
    Base *A =  new Derived();
    std::cout << std::endl << A->tryit();
}

出力:

 2
于 2012-07-03T08:48:12.057 に答える
0

このようなものを使用して回避策を実装するのは、どれほど「間違っている」でしょうか。

理論的には、あなたは何も悪いことをしていません。これは明確に定義された動作です。

それだけで、従うのは良い習慣ではありません。コードが乱雑になり、混乱を招きます。また、将来、他の子クラスに派生する
と扱いにくくなります。bar

于 2012-07-03T08:40:26.060 に答える