1. 虚函数与纯虚函数的概念
在学习面向对象编程时,我们经常听说类和对象,类可以看作是一种模板,而对象则是类的具体实例。
在一个类中,有些函数可以在子类中被重写,可以让子类定义自己的实现,而父类则提供一种默认的实现方式,这种函数称为虚函数。
但是有时候,父类中的函数并没有意义,只是为了让子类重写,这种函数可以声明为纯虚函数。
class Base {
public:
virtual void foo() {
// 默认实现方式
}
virtual void bar() = 0; // 纯虚函数
}
class Derived1 : public Base {
public:
void foo() {
// 重写了虚函数 foo
// 这里可以调用 Base::foo() 做一些初始化
}
void bar() {
// 重写了纯虚函数 bar
// 父类中没有提供默认实现,子类必须实现
}
}
class Derived2 : public Base {
public:
// 没有重写 foo
void bar() {
// 这里必须实现 bar
}
}
2. 虚函数和纯虚函数的区别
2.1 实现方式
虚函数可以在父类中实现,也可以在子类中覆盖,但是纯虚函数必须在子类中实现。
class Base {
public:
virtual void foo() { // 这里提供了默认实现方式
// ...
}
virtual void bar() = 0; // 这里没有提供实现
}
class Derived : public Base {
public:
void bar() { // 必须重写纯虚函数
// 实现方式
}
}
2.2 类型
虚函数提供一个默认实现,子类可以覆盖。而纯虚函数没有提供任何实现,只是为了让子类实现,也就是说纯虚函数是抽象的函数,它不能被声明为对象,因为它没有对应的实现,而虚函数可以被声明为普通的成员函数。
2.3 使用场景
虚函数主要用于实现运行时多态(动态绑定),子类对象可以替代父类对象使用。纯虚函数用于实现接口,父类中没有实现的函数(只有声明),由子类去实现(必须实现)。另外,纯虚函数也可以用于确保子类实现了父类中的某些函数,比如说定义了一些接口类,只是为了提供一些公共属性(方法),这时候这些方法就需要定义成纯虚函数,使用时子类必须实现这些方法才能使用接口。
class ISerializable {
public:
virtual void serialize() = 0; // 子类必须实现 serialize
};
class Person : public ISerializable {
public:
void serialize() {
// 序列化实现方式
}
};
3. 总结
虚函数提供了一种默认实现方式,但也可以被子类重写;纯虚函数没有提供任何实现,只是为了子类去实现。虚函数主要用于多态,而纯虚函数主要用于实现接口。总的来说,虚函数和纯虚函数都是面向对象编程中的重要概念,要掌握它们的使用场景和区别,这样才能更好地设计和实现面向对象的程序。