首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中使用上、下浇铸的原因是什么?

在C++中使用上、下浇铸的原因是什么?
EN

Stack Overflow用户
提问于 2017-07-14 13:19:36
回答 3查看 2.5K关注 0票数 0

我从http://www.studytonight.com/cpp/upcasting.php上读了关于上播和下播的描述

..。将子类的引用或指针转换为其超级类的引用或指针的行为称为向上转换。与上播相反的是下播,其中我们将超类的引用或指针转换为派生类的引用或指针。稍后我们将研究更多关于唐恩广播的内容。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-14 13:39:21

当有一个基类(几个类从中继承)时,我们通常需要一个指针来指向其中一个派生类。

例如,我们可以拥有一个动物类以及派生的狗和猫类:

代码语言:javascript
复制
class Animal {};

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

Dog dog;
Animal* a = &dog;

Cat cat;
Animal* b = &cat;

通常情况下,我们希望有一个指针可以指向这些对象之一。我们可以使用动物指针,因为狗和猫都是动物的类型。这就是上流社会的本质。我们向上转换一个派生类并将它表示为基类。

那下线呢?我们可以使用dynamic_cast来做到这一点:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2017-07-14 13:34:29

使用它们的主要原因是使多态成为可能。多态所需的另一种技术是迟/动态绑定

Upcasting允许我们使用基类接口的继承类(子类)。您可以使用相同的基类接口处理那些对象,而不需要知道它是什么具体的子类对象。

另一方面,需要向下转换,因为您可能希望获得子对象的特殊方法或成员变量。然后,你需要沮丧。

要向上或向下抛出,您可以安全地使用描述为dynamic_cast这里

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

要在基类和子类之间向上或向下转换,需要指针(type*)或引用类型(type&),因为只有对象的视图才会改变,而不是具体对象本身。如果使用对象本身,对象切片就会发生,并且会丢失继承类的信息。

我给你一个例子,什么时候用完-和下注。假设您有一个父类Car和2个从Car继承的类PorscheFord。现在,您有一个std::vector<Car*> cars,例如,您想要放进不同的汽车。你会做这样的事情:

代码语言:javascript
复制
std::vector<Car*> cars;
cars.push_back(new Porsche()); /* implicit upcast */
cars.push_back(new Ford());    /* implicit upcast */

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

如果你现在想买那些车,你可以:

代码语言:javascript
复制
Car*     porscheAsCar = cars.at(0);
Porsche* porsche      = dynamic_cast<Porsche*>(cars.at(0));

例如,现在Car类确实有一个drive()方法,而Porsche类有一个实现的driveFast()方法。你可以进入它们:

代码语言:javascript
复制
porscheAsCar->drive(); /* Call Porsche drive() method     */
porsche->drive();      /* Call Porsche drive() method     */
porsche->driveFast();  /* Call Porsche driveFast() method */

即使我们用基类接口调用drive方法,如果方法是用虚拟声明的,它也将是Porschedrive方法。通过向下转换,您可以访问特定于继承类的方法/成员变量。但是,如果Car实际上是一个Porsche而不是Ford,这是可能的。

你看这里上有一些输出的完整示例。

票数 3
EN

Stack Overflow用户

发布于 2017-07-14 13:59:48

在我看来,你使用的网站质量很差。我试着读了一些文章:它们不是不正确的,但它们甚至不适合那些试图进入C++世界的人,他们有一点编程经验。即使是我,以我15年的专业C++程序员的经验,发现它有点压力阅读。

正如有人说的,一本好书,即使是免费的,也是一个更好的解决方案。谷歌是你最好的搜索朋友。这是对你问题的一个很好的回答,比我所能写的任何东西都要完整:https://www.tutorialcup.com/cplusplus/upcasting-downcasting.htm

祝你今天过得愉快,斯坦。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45104067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档