提问人:roi_saumon 提问时间:3/29/2023 最后编辑:roi_saumon 更新时间:3/29/2023 访问量:138
上投真的是选角吗?
Is upcasting really a casting?
问:
我对 c++ 中的术语 upcast 感到困惑(例如这里)。真的是选角吗?例如,当我将 an 转换为 时,我希望转换类型的行为与 .但是,如果我将派生类向上转换为基类,则似乎强制转换的对象的行为与基类的对象不完全相同,如以下代码所示:int
double
double
class Base {
public:
virtual void print() { cout << "base" << endl; }
};
class Derived :public Base {
public:
void print() { cout << "derived" << endl; }
};
void main()
{
// Upcasting
Derived d;
Base* pBase = &d;
// test
Base b;
Base* pBase2 = &b;
if (dynamic_cast<Derived*>(pBase));
{
cout << "1st upcasting ok" << endl;
}
if (dynamic_cast<Derived*>(pBase2))
{
cout << "2nd ucasting ok" << endl;
}
}
输出:
1st upcasting ok
答:
你提出了一个好的观点。在 C++ 中,从技术上讲,上转换不是与将 int 转换为双精度值相同意义上的强制转换操作,因为不会发生对象的实际转换。
当派生类对象被上行转换为基类指针时,派生类对象将被视为基类的对象。实际对象仍然是派生类对象,但指向该对象的指针可以被视为基类指针,只允许访问基类的成员。
在您的示例中,向上转换的对象只能访问 Base 类成员,即使它实际上是 Derived 类的对象。对 upcast 对象调用的 print 函数将调用 Base 类的 print 函数,因为这是基类中定义的函数的版本。但是,如果在 Base 类中将 print 函数声明为虚拟函数,并在 Derived 类中重写,则如果该对象实际上是 Derived 对象,则将调用 Derived 类的 print 函数,即使它被上调到 Base 指针也是如此。
因此,虽然从技术上讲,上转换不是与类型转换相同意义上的强制转换操作,但它是将派生类对象视为 C++ 中基类对象的常用方法。
评论
Base b = d;
dynamic_cast
A
B
B
A* a = new B
a
B
A
A
B* casted = static_cast<B*>(a)
B* casted = dynamic_cast<B*>(a)
B*
B
Upcast 并不是严格意义上的 C++ 术语。 on a pointer 不会创建新对象。dynamic_cast
在第一种情况下,你有类类型的对象,即基类之一。如果将其地址分配给指向 的指针,则仍具有相同的对象。因为派生类是动态类型,而它的静态类型是 。您需要正确获取指向动态类型的指针。Derived
Base
Base
pBase
Base
dynamic_cast
在第二种情况下,静态和动态类型是相同的。您没有 的对象。 返回 null 指针。Derived
dynamic_cast
评论
dynamic_cast<Derived*>(pBase2)
失败,因为不指向对象。这就是 .pBase2
Derived
dynamic_cast
dynamic_cast<Derived*>(pBase)