基类对象从派生类对象转换(类型从下到上的转换)
红色部分是派生类特有的成员,蓝色部分是派生类从基类继承的成员。
int main () {
Base b;
Derive d;
b = d;
return 0;
}
我们将派生类赋给了基类,这是被允许的!因为本质上,这属于类型从下到上的转换。
当派生类对象赋值给基类对象时,只有派生类对象中的基类部分会被复制到基类对象中,这个过程通常称为“对象切割”(Object Slicing),其中派生类独有的任何属性或方法都不会被复制。
基类对象转换为派生类对象(类型从上到下的转换)
int main () {
Base b;
Derive d;
//编译器报错!
//d = b;
d = static_cast<Derived>(b);
return 0;
}
从基类对象到派生类对象的转换在 C++ 中不是隐式允许的,因为这种转换通常是不安全的。如果必须进行此类转换,需要使用 static_cast,但这种做法通常不推荐,因为它违背了面向对象的多态原则,并且可能导致运行时错误。
⭐️基类指针从派生类对象赋值(类型从下到上的转换)
int main () {
Derive d;
Base* pb = &d;
return 0;
}
这种转换在 C++ 中是安全的且被隐式允许。基类指针可以指向派生类对象,这是实现多态性的基础。
-
多态性(Polymorphism):
- 多态性是面向对象编程(OOP)的核心特征之一,它允许通过基类指针(或引用)来调用派生类的方法,从而实现在运行时决定具体哪个函数被执行(动态绑定)。这使得代码更加灵活和可扩展。
-
抽象性(Abstraction):
- 通过使用基类指针指向派生类对象,程序设计可以在一定程度上忽略对象的具体类型,只需关注接口(基类定义的方法)的使用。这种抽象性是大型软件系统设计中减少复杂性的关键。
派生类指针从基类对象赋值(类型从上到下的转换)
Base b;
//报错!
//Derived* pd = &b;
Derived* pd = dynamic_cast<Derived*>(&b); // 运行时检查,需基类有虚函数
- 从基类指针或引用到派生类指针的转换在 C++ 中不是隐式允许的,因为它不安全。可以使用 dynamic_cast 进行转换,这需要运行时类型信息(RTTI)的支持,并且基类必须至少有一个虚函数。如果转换不合法,dynamic_cast 将返回 nullptr。
- 如果使用 static_cast 强制转换,编译器不会进行类型安全检查,这可能导致不安全的行为。