在C ++中使用向上转换和向下转换的原因是什么?

时间:2017-07-14 13:19:36

标签: c++

我从http://www.studytonight.com/cpp/upcasting.php阅读了有关向上转发和向下转发的说明:

  

[...]将Sub类的引用或指针转换为其Super类的引用或指针的行为称为Upcasting。与Upcasting相反的是Downcasting,我们将Super class的引用或指针转换为派生类的引用或指针。我们稍后会研究更多有关向下倾斜的信息。

但我不明白为什么在C ++中使用向上转换和向下转换。你能解释为什么使用这些机制吗?

3 个答案:

答案 0 :(得分:1)

使用它们的主要原因是使polymorphism成为可能。多态性所需的另一种技术是late/dynamic binding

Upcasting允许我们将继承的类(子类)与基类接口一起使用。您可以使用相同的基类接口处理这些对象,而无需知道它是什么具体的子类对象 另一方面,需要向上转换,因为您可能想要获取子对象的特殊方法或成员变量,然后您需要向上转换。
要进行强制转换,您可以安全地使用dynamic_cast所述的here

  

如果强制转换成功,dynamic_cast将返回new_type类型的值。如果强制转换失败并且new_type是指针类型,则返回该类型的空指针。如果强制转换失败且new_type是引用类型,则抛出与std::bad_cast类型的处理程序匹配的异常。

要在基类和子类之间向上或向下播放,您需要指针(type*)或引用类型(type&),因为只有对象的视图不会改变具体对象本身。如果您将使用类型(type)本身object slicing将发生,您将丢失继承类的信息。

我举一个例子来说明何时使用向上和向下转换。假设您拥有父类Car以及从Porsche继承的2个类FordCar。现在你有一个std::vector<Car*> cars,例如你想要放入不同的汽车。你可以这样做:

std::vector<Car*> cars;
cars.push_back(new Porsche()); /* implicit upcast */
cars.push_back(new Ford());    /* implicit upcast */

好处是你有一个“不同”对象的向量,这是可能的,因为它们都有相同的父类。

如果您现在想要获得这些车,您可以这样做:

Car*     porscheAsCar = cars.at(0);
Porsche* porsche      = dynamic_cast<Porsche*>(cars.at(0));

现在举例来说,Car类确实有drive()方法,Porsche类实现了driveFast()方法。你可以访问它们:

porscheAsCar->drive(); /* Call Porsche drive() method     */
porsche->drive();      /* Call Porsche drive() method     */
porsche->driveFast();  /* Call Porsche driveFast() method */

即使我们使用基类接口调用drive方法,如果使用virtual声明方法,它也将是drive的{​​{1}}方法。使用向下转换,您可以访问特定于继承类的方法/成员变量。但是,如果Porsche实际上是Car而不是Porsche,那么这是可能的。

ideone see here上有一些输出的完整示例。

答案 1 :(得分:1)

当有一个基类时,我们经常需要一个可以指向其中一个派生类的指针。

例如,我们可以拥有一个Animal类和派生的Dog和Cat类:

class Animal {};

class Dog : public Animal {};
class Cat : public Animal {};

Dog dog;
Animal* a = &dog;

Cat cat;
Animal* b = &cat;

通常,我们希望有一个指针可以指向其中一个对象。我们可以使用Animal指针,因为Dog和Cat都是Animal的一种类型。这是向上倾向的本质。我们向上转换派生类并将其表示为基类。

向下倾斜怎么样?我们可以使用dynamic_cast:

Cat c;
Animal* animal = &c; //Implicit upcast
Cat* cat = dynamic_cast<Cat*>(animal); //Explicit downcast
//Check if dynamic cast worked:
if(!cat) {
    //ERROR: Not a cat object
}

答案 2 :(得分:0)

以我的拙见,您使用的网站质量很差。我试过阅读一些文章:它们并不是错误的,但它们甚至不适合那些试图通过一点编程经验进入C ++世界的人。即使我凭借我15年的专业C ++程序员经验,也发现阅读时有点压力。

有人说一本好书,即使是免费的,也是一个更好的解决方案。 Google是您搜索的最佳朋友。这是对你的问题的一个很好的答案,比我能写的更完整:https://www.tutorialcup.com/cplusplus/upcasting-downcasting.htm

祝你有个美好的一天,Ste。