对于多态来说,有两种实现形式,一种时用派生类向基类赋值,另一种是在基类指针中赋值派生类地址
时间: 2024-03-31 10:36:45 浏览: 55
实际上,这两种实现形式并不是多态的两种实现方式,而是多态的两种体现方式。多态是面向对象中的一个重要概念,它允许我们以一种统一的方式处理不同类型的对象,即通过基类指针或引用调用派生类的函数。而基类指针或引用可以通过派生类向基类赋值或者在基类指针中赋值派生类地址来实现多态的体现。
当我们使用派生类向基类赋值时,实际上是将派生类对象转换为基类对象。这种做法的好处是可以实现对象的向上转型,使得派生类对象可以赋值给基类对象,从而可以在程序中以基类对象的方式来操作派生类对象,但同时也会存在一些问题,比如无法调用派生类独有的函数或成员变量等。
而在基类指针中赋值派生类地址,则是将派生类对象的地址赋值给基类指针,这种做法的好处是可以在程序中直接操作派生类对象,而且可以调用派生类独有的函数或成员变量等。但同时也需要注意,这种做法需要保证基类指针指向的对象是派生类对象,否则可能会出现不可预期的结果。
因此,在实际编程中,我们选择哪种多态的体现方式,需要根据具体的情况来决定,以达到最好的效果。
相关问题
定义一个抽象类,然后对抽象类进行扩展。 1 定义交通工具 Vehicle 为抽象类,在该类中定义交通工具类别,重量,定义一个纯虚 函数 show。 2 定义基类派生小车类 Car,在该类中定义 Car 类的类别,重量,实现 show 函数 3 定义基类派生小车类 Truck,在该类中定义 Truck 类的类别,重量,实现 show 函数 4 建立主程序,在主程序中定义一个基类的指针,分别赋值不同的派生类,调用派生类 的 show 函数,输出该类的类型,实现多态。
可以这样来定义抽象类和对其进行扩展:
```cpp
#include <iostream>
using namespace std;
// 定义交通工具类
class Vehicle {
protected:
string category; // 类别
double weight; // 重量
public:
// 纯虚函数,需要在派生类中实现
virtual void show() = 0;
};
// 小车类
class Car: public Vehicle {
public:
Car(string cat, double w) {
category = cat;
weight = w;
}
// 实现show函数
void show() {
cout << "小车类别:" << category << endl;
cout << "小车重量:" << weight << "吨" << endl;
}
};
// 卡车类
class Truck: public Vehicle {
public:
Truck(string cat, double w) {
category = cat;
weight = w;
}
// 实现show函数
void show() {
cout << "卡车类别:" << category << endl;
cout << "卡车重量:" << weight << "吨" << endl;
}
};
int main() {
// 定义基类指针并分别赋值不同的派生类对象
Vehicle* vehicle1 = new Car("轿车", 1.5);
Vehicle* vehicle2 = new Truck("货车", 5.0);
// 调用派生类的show函数,实现多态
vehicle1->show();
cout << endl;
vehicle2->show();
// 释放内存
delete vehicle1;
delete vehicle2;
return 0;
}
```
这段代码定义了一个抽象类`Vehicle`,其中包含了类别和重量两个成员变量,并声明了一个纯虚函数`show`。然后通过派生类`Car`和`Truck`继承了`Vehicle`类,并实现了`show`函数。在主程序中,我们定义了一个基类指针,并分别赋值不同的派生类对象,在调用派生类的`show`函数时实现了多态,输出了不同派生类的类型和相关属性信息。最后,记得释放内存。
qt初始化基类指针,在基类指针构造中如果识别到是某个派生类,在转换为派生类
的指针时需要使用动态类型转换(dynamic_cast)。这样可以避免在多态的情况下出现指针偏移量不正确的问题。在使用dynamic_cast时需要注意以下几点:
1. 基类必须有虚函数,否则无法使用dynamic_cast进行转换。
2. dynamic_cast会在运行时进行类型检查,如果转换失败会返回nullptr(对于指针类型)或者抛出std::bad_cast异常(对于引用类型)。
3. dynamic_cast只能用于指针或引用类型的转换,不能用于基本数据类型之间的转换。
下面是一个示例代码:
```c++
#include <iostream>
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
void foo() { std::cout << "Derived::foo" << std::endl; }
};
int main() {
Base* base = new Derived();
Derived* derived1 = dynamic_cast<Derived*>(base);
if (derived1 != nullptr) {
derived1->foo();
}
Base another_base;
try {
Derived& derived2 = dynamic_cast<Derived&>(another_base);
} catch (std::bad_cast& e) {
std::cout << e.what() << std::endl;
}
delete base;
return 0;
}
```
在上面的代码中,我们首先创建了一个Derived对象,并将其赋值给一个Base指针。然后我们使用dynamic_cast将基类指针转换为派生类指针,并调用了派生类的foo()函数。接着,我们创建了一个Base对象,并试图将其转换为Derived引用,但由于类型不匹配,dynamic_cast抛出了std::bad_cast异常。最后我们释放了动态分配的内存。
阅读全文