C++ - 向上转换和向下转换

Mih*_*hai 1 c++ inheritance class downcast upcasting

在我的例子中:

在向上看,第二次d.print()打电话不应打印"基地"吗?

是不是"d"派生对象上传到基类对象?

在低迷时期,它有什么优势?

你能用实际的方式解释上传和下传吗?

#include <iostream>
using namespace std;

class Base {
public:
    void print() { cout << "base" << endl; }
};

class Derived :public Base{
public:
    void print() { cout << "derived" << endl; }

};

void main()
{
    // Upcasting
    Base *pBase;
    Derived d;
    d.print();
    pBase = &d;
    d.print();

    // Downcasting
    Derived *pDerived;
    Base *b;
    pDerived = (Derived*)b;
}
Run Code Online (Sandbox Code Playgroud)

vso*_*tco 8

向上转换在C++中是隐含的,并且在处理虚拟分派时会被大量使用.换句话说,您有一个指针Base,您可以从该指针访问整个类层次结构的公共接口,并且可以在运行时完成选择.这假定您的界面功能已标记virtual.例:

Base* pBase; 
cin >> x; 
if(x == 0) // this is done at runtime, as we don't know x at compile time
    pBase = new Derived1;
else
    pBase = new Derived2;

pBase->draw(); // draw is a virtual member function
Run Code Online (Sandbox Code Playgroud)

在运行时完成调度的这些情况下,它非常有用.简单地说,upcasting允许将派生类视为基类(通过其通用接口).

向下投射不太有用,只要有人可以避免IMO.通常是设计不好的标志,因为很少需要将Base对象转换为派生对象.它可以通过dynamic_cast像(例如,检查结果)来完成

Base* pBase = new Derived; // OK, the dynamic type of pBase is Derived
Derived* pDerived = dynamic_cast<Derived*>(pBase);
if(pDerived) // always test  
{
    // success
}
else
{
    // fail to down-cast
}
Run Code Online (Sandbox Code Playgroud)

此链接提供了一个非常有用的介绍主题.

  • @Poriferous我希望你意识到`Base*p = new Derived`是(隐含的)向上转换,而不是向下转换.向上转换的方式不仅仅是向下转换.同样,IMO,`dynamic_cast`应该稀疏地使用. (2认同)

Mih*_*dor 7

您需要使用虚拟方法才能启用RTTI

在您的情况下,由于您使用的是 C++,您应该依赖更安全的转换机制。因此,(Derived*)b您应该使用dynamic_cast<Derived*>(b). 这允许您确保您实际上拥有一个指向基类(接口)对象的指针,该对象是通过转换类型的对象获得的Derived本页提供了进一步的解释。