对象之间的类型转换
1. 向上类型转换(Upcasting)
向上类型转换是将派生类对象的指针或引用转换为基类类型的指针或引用。它是自动、安全的,不需要显式的类型转换操作。
#include <iostream>
class Base {
public:
virtual void show() {
std::cout << "Base class" << std::endl;
}
};
class Derived : public Base {
public:
void show() override {
std::cout << "Derived class" << std::endl;
}
};
int main() {
Derived d;
Base* basePtr = &d; // 向上类型转换,自动进行
basePtr->show(); // 返回 "Derived class" 因为 Base 的 show() 是虚函数
return 0;
}
在上述代码中,我们将 Derived
类对象的指针 d
赋值给 Base
类的指针 basePtr
,这是一个向上类型转换。这种类型转换是自动且安全的,因为派生类对象始终包含基类对象。
2. 向下类型转换(Downcasting)
向下类型转换是将基类对象的指针或引用转换为派生类类型的指针或引用。这种转换不自动进行,因为一个基类可以有多个派生类,需要进行运行时类型识别(RTTI)。这通常通过 dynamic_cast
实现。
#include <iostream>
class Base {
public:
virtual ~Base() = default; // 确保有一个虚拟析构函数进行正确的RTTI
virtual void show() {
std::cout << "Base class" << std::endl;
}
};
class Derived : public Base {
public:
void show() override {
std::cout << "Derived class" << std::endl;
}
};
int main() {
Base* basePtr = new Derived;
// 向下类型转换,使用 dynamic_cast
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
derivedPtr->show(); // 输出 "Derived class"
} else {
std::cout << "Conversion failed" << std::endl;
}
delete basePtr; // 确保正确释放内存
return 0;
}
在上述代码中,我们使用 dynamic_cast
将 Base
类对象的指针 basePtr
转换为 Derived
类对象的指针 derivedPtr
。这是一个向下类型转换,需要 dynamic_cast
和虚拟函数支持以实现运行时类型识别。
指针与引用之间的转换
C++ 指针和引用的转换主要基于指向对象类型的兼容性,可以通过以下规则进行转换:
指针之间的转换:
- 派生类指针可以自动转换为基类指针(向上转换)。
- 基类指针转换为派生类指针时需要使用
dynamic_cast
,确保类型安全。
引用之间的转换:
- 派生类引用可以自动转换为基类引用(向上转换)。
- 基类引用转换为派生类引用时需要使用
dynamic_cast
,与指针类似。
#include <iostream>
class Base {
public:
virtual ~Base() = default;
virtual void show() const { std::cout << "Base class" << std::endl; }
};
class Derived : public Base {
public:
void show() const override { std::cout << "Derived class" << std::endl; }
};
void display(const Base& b) {
b.show(); // 基类引用
}
int main() {
Derived d;
Base& baseRef = d; // 向上类型转换,自动进行
baseRef.show(); // 返回 "Derived class"
try {
Derived& derivedRef = dynamic_cast<Derived&>(baseRef); // 向下类型转换
derivedRef.show(); // 返回 "Derived class"
} catch (const std::bad_cast& e) {
std::cout << "Conversion failed: " << e.what() << std::endl;
}
return 0;
}
在上述代码中,通过引用进行的是类似的转换模式:
Base& baseRef = d;
是一个向上类型转换,将Derived
类对象引用转换为Base
类引用。dynamic_cast<Derived&>(baseRef);
是一个向下类型转换,通过运行时类型识别确保安全转换。
总结,理解向上和向下类型转换以及指针和引用之间的转换是对C++继承机制的深入掌握。向上类型转换自动且安全,而向下类型转换需要 dynamic_cast
和运行时类型识别(RTTI)技术来保障类型安全。