在C++中,函数重写(Function Overriding)是一种面向对象编程的概念,它允许派生类重新定义基类中已经定义的虚函数。函数重写用于实现多态性,使得程序能够在运行时选择调用哪个版本的函数,以便适应不同的对象类型。
以下是函数重写的基本原则:
基类中的虚函数声明: 在基类中,通过使用关键字 virtual 来声明一个虚函数。虚函数在基类中的声明为:
class Base {
public:
virtual void myFunction() {
// 函数体
}
};
派生类中的函数重写: 派生类可以通过重新定义基类中的虚函数来实现函数重写。在派生类中,函数的声明和定义需要与基类中的虚函数一致,包括函数签名和返回类型。使用 override 关键字可以确保派生类中的函数确实是对基类虚函数的重写。
class Derived : public Base {
public:
void myFunction() override {
// 重新定义的函数体
}
};
运行时多态性: 使用基类指针或引用指向派生类对象,并调用虚函数时,将会根据对象的实际类型调用相应的函数。这种行为称为运行时多态性。
int main() {
Base* basePtr = new Derived();
basePtr->myFunction(); // 调用派生类中的函数
delete basePtr;
return 0;
}
总体来说,函数重写允许在派生类中提供对基类虚函数的新实现,使得代码更具灵活性和可扩展性。请注意,只有虚函数才能被重写。
下面这个是实例:
#include <iostream>
#include <string>
// 基类(父类)
class Animal {
public:
// 纯虚函数
virtual void sleep() const = 0;
// 虚函数
virtual std::string makeSound() const {
return "Animal makes a generic sound";
}
};
// 派生类(子类)1
class Dog : public Animal {
public:
// 重写基类中的虚函数
std::string makeSound() const override {
return "Dog barks: Woof! Woof!";
}
// 实现基类的纯虚函数
void sleep() const override {
std::cout << "Dog is sleeping in its bed." << std::endl;
}
// Dog 类自己的其他成员函数
void fetch() const {
std::cout << "Dog fetches a ball." << std::endl;
}
};
// 派生类(子类)2
class Cat : public Animal {
public:
// 重写基类中的虚函数
std::string makeSound() const override {
return "Cat meows: Meow! Meow!";
}
// 实现基类的纯虚函数
void sleep() const override {
std::cout << "Cat is napping on the windowsill." << std::endl;
}
// Cat 类自己的其他成员函数
void climbTree() const {
std::cout << "Cat climbs a tree." << std::endl;
}
};
int main() {
// 创建基类对象
// Animal genericAnimal; //基类是抽象类(因为有虚函数),不能被实例化
// 调用基类的虚函数
// std::cout << "Generic Animal Sound: " << genericAnimal.makeSound() << std::endl;
std::cout << "------------------------" << std::endl;
// 创建派生类对象1
Dog myDog;
// 调用派生类的虚函数,实际上调用的是子类的版本
std::cout << "Dog Sound: " << myDog.makeSound() << std::endl;
// 调用派生类自己的其他成员函数
myDog.fetch();
std::cout << "------------------------" << std::endl;
// 创建派生类对象2
Cat myCat;
// 调用派生类的虚函数,实际上调用的是子类的版本
std::cout << "Cat Sound: " << myCat.makeSound() << std::endl;
// 调用派生类自己的其他成员函数
myCat.climbTree();
return 0;
}