浅谈C++之虚函数和重写

时间:2024-10-23 07:39:45

一、基本介绍

        在C++中,虚函数(virtual function)是一种允许在派生类(子类)中重写(override)函数的行为的成员函数。使用虚函数可以实现运行时多态(runtime polymorphism),即在程序运行时决定调用哪个函数。        

二、简单应用

声明虚函数

在基类中声明虚函数,通常使用virtual关键字。这样声明的函数可以在派生类中被重写。

class Base {
public:
    virtual void show() {
        std::cout << "Base show" << std::endl;
    }
    virtual ~Base() {} // 虚析构函数,确保删除派生类对象时调用正确的析构函数
};

重写虚函数

在派生类中重写基类的虚函数,不需要使用virtual关键字,但可以为了提高代码清晰度而使用。

class Derived : public Base {
public:
    void show() override { // 使用override关键字,确保我们确实重写了基类的函数
        std::cout << "Derived show" << std::endl;
    }
};

使用虚函数实现多态

通过基类指针或引用调用虚函数时,会根据对象的实际类型调用相应的函数。

Base* basePtr = new Derived();
basePtr->show(); // 输出 "Derived show"
delete basePtr;

在这个例子中,尽管basePtrBase类型的指针,但它实际上指向一个Derived类型的对象。因此,调用show()函数时,会调用Derived类中的版本。

虚析构函数

为了确保删除通过基类指针删除派生类对象时能够正确地调用派生类的析构函数,基类应该声明一个虚析构函数。

class Base {
public:
    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    ~Derived() {
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    delete basePtr; // 输出 "Derived destructor" 和 "Base destructor"
    return 0;
}

在这个例子中,如果没有在Base类中声明虚析构函数,那么在删除basePtr时将不会调用Derived类的析构函数,可能导致资源泄漏。

纯虚函数

如果一个类希望强迫所有派生类都必须实现某个函数,可以声明一个纯虚函数(pure virtual function)。

class Base {
public:
    virtual void show() = 0; // 纯虚函数
};

声明纯虚函数的类被称为抽象类(abstract class),它不能被直接实例化,只能作为基类来使用。

虚函数是C++实现多态的关键特性之一,它提供了一种灵活的方式来实现接口和实现的解耦。