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 回答