当在 C++ 中使用 virtual
和抽象类时,可以实现多态性和定义纯虚函数。下面我会详细解释这两个概念,并给出一个更详细的示例说明。
virtual
关键字:
virtual
是用于实现多态性的关键字,它可以在基类中声明虚函数,并在派生类中进行重写。virtual
关键字可以实现动态绑定(dynamic binding),也称为后期绑定(late binding)。override
关键字显式标记重写的函数,可以提高代码的可读性和可维护性。抽象类和纯虚函数:
= 0
来标识。下面是一个更详细的示例,说明 virtual
和抽象类的使用:
#include
class Shape {
public:
virtual void draw() = 0; // 纯虚函数,使 Shape 成为抽象类
virtual double area() const = 0; // 另一个纯虚函数
virtual ~Shape() {} // 虚析构函数,确保正确释放派生类资源
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override {
std::cout << "Drawing a circle." << std::endl;
}
double area() const override {
return 3.14159 * radius * radius;
}
~Circle() {
std::cout << "Circle destructor called." << std::endl;
}
};
class Rectangle : public Shape {
private:
double length;
double width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
void draw() override {
std::cout << "Drawing a rectangle." << std::endl;
}
double area() const override {
return length * width;
}
~Rectangle() {
std::cout << "Rectangle destructor called." << std::endl;
}
};
int main() {
Shape* shapes[2];
shapes[0] = new Circle(5.0);
shapes[1] = new Rectangle(3.0, 4.0);
for (int i = 0; i < 2; i++) {
shapes[i]->draw();
std::cout << "Area: " << shapes[i]->area() << std::endl;
}
delete shapes[0];
delete shapes[1];
return 0;
}
在上述示例中,Shape
是一个抽象类,它包含两个纯虚函数 draw()
和 area()
。Circle
和 Rectangle
是派生类,它们继承自 Shape
并重写了这两个纯虚函数。
在 main()
函数中,我们创建了一个 Shape*
数组,并用 Circle
和 Rectangle
的对象初始化数组元素。通过使用基类指针调用 draw()
和 area()
函数时,根据指针实际指向的对象类型,调用的是相应派生类的函数。这展示了多态性的作用,即在运行时根据对象的实际类型来动态绑定函数调用。
输出结果为:
Drawing a circle.
Area: 78.5398
Drawing a rectangle.
Area: 12
Circle destructor called.
Rectangle destructor called.
从输出结果可以看出,在循环中通过基类指针调用派生类的函数时,正确地调用了相应的派生类的函数。同时,在程序结束时,通过基类指针删除了派生类的对象,确保了正确的资源释放。
这个示例展示了 virtual
关键字的使用,它允许在派生类中重写基类的函数,并通过基类指针调用适当的派生类函数,实现了多态性。同时,抽象类和纯虚函数的使用定义了一个接口和行为的框架,要求派生类实现特定的功能,提高了代码的灵活性和可扩展性。