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

qpgpyjmq  于 2023-05-30  发布在  其他
关注(0)|答案(3)|浏览(206)

在我的例子中:
在向上转换时,第二个d.print()不应该调用print“base”吗?
它不是“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;
}
rekjcdws

rekjcdws1#

向上转换在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

在这些调度是在运行时完成的情况下,它非常有用。简单地说,向上转换允许将派生类视为基类(通过其公共接口)。
下投是不太有用的,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
}

This link提供了一个非常有用的主题介绍。

qcuzuvrc

qcuzuvrc2#

您需要使用虚拟方法来启用RTTI
在您的例子中,由于您使用的是C++,因此应该依赖更安全的强制转换机制。因此,您应该使用dynamic_cast<Derived*>(b)而不是(Derived*)b。这使您可以确保您实际拥有一个指向基类(接口)的对象的指针,该对象是通过强制转换Derived类型的对象获得的。This page提供了进一步的解释。

6mw9ycah

6mw9ycah3#

如果你想调用print“Base”,那么你应该这样做,在这里我们将派生类对象向上转换到这个基类对象,所以当我们调用pBase->print()时,它会转到基类并调用它,但是如果print函数是虚函数,那么它将被调用到类驱动,因为它在驱动类中覆盖了这个函数。

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

}

相关问题