15

「同じタイトルの質問が何十もあると思います。それらの多くは重複しています。私のものも重複している可能性がありますが、見つかりませんでした。そのため、非常にすっきりと短く、シンプルにしようとしています。」

私はこのような階層を持っています:

class Shape {
public:
   virtual void virtualfunc()  { std::cout << "In shape\n"; }
};

class Circle: public Shape {
public:
   void virtualfunc()  { std::cout << "In Circle\n"; };
};

ポインタを使用してクラスを使用すると、期待どおりに関数が呼び出されます。

int main() {
   Shape shape_instance;
   Shape* ref_shape = &shape_instance ;
   Circle circle_instance;
   Circle* ref_circle = &circle_instance;

   ref_shape = dynamic_cast<Shape*> (ref_circle);
   ref_shape->virtualfunc();
}

ここで、プログラムはvirtualfunc()派生クラスのを呼び出し、結果は当然次のようになります。In Circle

ここで、ポインターを削除し、代わりに参照を使用して、同じ結果を取得したいと思います。main()だから私はこのように見えるように些細な変更を加えます:

int main() {
   Shape shape_instance;
   Shape& ref_shape = shape_instance;
   Circle circle_instance;
   Circle& ref_circle = circle_instance;

   ref_shape = dynamic_cast<Shape&>(ref_circle);
   ref_shape.virtualfunc();
}

しかし今回は、プログラムがvirtualfunc()基本クラスのを呼び出し、結果は次のようになります。In Shape

欠落している参照の概念と、ポインターバージョンで取得した結果を取得するためにmain()の参照を変更する方法を教えていただければ幸いです。

ありがとうございました

4

4 に答える 4

18

参照を再配置することはできません。初期化で参照を初期化すると、参照先オブジェクトのエイリアスになり、それと区別できなくなります。後者の割り当て:

ref_shape = dynamic_cast<Shape&>(ref_circle);

本当に意味:

shape_instance = dynamic_cast<Shape&>(ref_circle);

一方、新しい参照をオブジェクトにバインドすることもできます (dynamic_cast参照から派生への参照から基底への参照への変換は暗黙的であるため、 は必要ありません)。

Shape & another_ref = ref_circle;
another_ref.virtualfunc();          // Dispatches to Circle::virtualfunc
于 2013-03-14T04:13:06.123 に答える
6

これは、あなたCircleが に変わっているところShapeです。

ref_shape = dynamic_cast<Shape&>(ref_circle);
//        ^ here
ref_shape.virtualfunc();

ref_shapeへの参照としてすでに定義されていますshape_instance

参照は再割り当てできないため、参照自体をコピーしていません実際のオブジェクトをオブジェクトにコピーしていShapeます。に格納されていshape_instanceます。

このコードを試すことで、これを確認できます。印刷されますIn Circle

dynamic_cast<Shape&>(ref_circle).virtualfunc();
于 2013-03-14T04:05:56.520 に答える
4

次のことを行う必要があります。

#include <iostream>

 class Shape {
  public:
   virtual void virtualfunc()  { std::cout << "In shape\n"; }
 };

 class Circle: public Shape {
   public:
   void virtualfunc()  { std::cout << "In Circle\n"; };
 };

 int main() {
    Shape shape_instance;
    //Shape& ref_shape = shape_instance;
    Circle circle_instance;
    Circle& ref_circle = circle_instance;

    Shape& ref_shape = dynamic_cast<Shape&>(ref_circle);
    ref_shape.virtualfunc();
}

期待どおり、Circle で出力されます。

于 2013-03-14T04:00:08.787 に答える
1

あなたが達成/表示しようとしていること (つまり、動的仮想関数バインディング) を正しく理解していれば、おそらく次のコードが役立ちます。

#include <iostream>
using namespace std;

class Shape {
  public:
    virtual void virtualfunc()  { std::cout << "In shape\n"; }
};

class Circle: public Shape {
  public:
    void virtualfunc()  { std::cout << "In Circle\n"; };
};

int main() {
  Circle circle_instance;

  // don't care what kind of Shape
  Shape &someShape = circle_instance;

  someShape.virtualfunc();
}

ここでは、someShapeがバインドされているShapeか、任意の派生クラスにバインドでき、仮想関数が実際の動的型で呼び出されることがわかります。これは印刷されますIn Circle。証明: http://ideone.com/A1UvrR

の必要はありませんdynamic_cast

于 2013-03-14T03:57:34.377 に答える