C++虚函数

虚函数(Virtual Function)是C++中实现多态(Polymorphism)的关键机制。多态允许你通过基类指针或引用来调用派生类的成员函数,从而实现动态绑定(Dynamic Binding)。
虚函数在运行时决定调用哪一个函数,而不是在编译时决定。

1. 基本概念

  • 虚函数:在基类中使用virtual关键字声明的成员函数。派生类可以重写(override)这个函数。
  • 多态:通过基类指针或引用调用派生类的重写函数。
  • 动态绑定:在运行时决定调用哪一个函数,而不是在编译时。

2. 基本语法

在基类中声明虚函数时使用virtual关键字:

class Base {
public:
    virtual void show() {
        std::cout << "Base class" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override { // 重写基类的虚函数
        std::cout << "Derived class" << std::endl;
    }
};

示例代码

#include <iostream>

// 基类
class Base {
public:
    virtual void show() {
        std::cout << "Base class" << std::endl;
    }
};

// 派生类
class Derived : public Base {
public:
    void show() override {
        std::cout << "Derived class" << std::endl;
    }
};

void display(Base* obj) {
    obj->show(); // 调用虚函数
}

int main() {
    Base base;
    Derived derived;

    display(&base);    // 输出 "Base class"
    display(&derived); // 输出 "Derived class"

    return 0;
}

输出:

Base class
Derived class

3. 纯虚函数和抽象类

纯虚函数是没有实现的虚函数,用于定义接口。包含纯虚函数的类称为抽象类,不能实例化。

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

class ConcreteDerived : public AbstractBase {
public:
    void show() override {
        std::cout << "ConcreteDerived class" << std::endl;
    }
};

int main() {
    // AbstractBase obj; // 错误:不能实例化抽象类
    ConcreteDerived derived;
    derived.show(); // 输出 "ConcreteDerived class"
    return 0;
}

输出:

ConcreteDerived class

4. 虚析构函数

在使用多态时,如果基类指针指向派生类对象,应该将基类的析构函数声明为虚函数(virtual),以确保正确调用派生类的析构函数。

#include <iostream>

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

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

int main() {
    Base* obj = new Derived();
    delete obj; // 调用Derived的析构函数,然后调用Base的析构函数
    return 0;
}

输出:

Derived destructor called
Base destructor called

5. 虚函数表(VTable)

虚函数的实现依赖于虚函数表(VTable)。每个包含虚函数的类都有一个虚函数表,表中存储了指向该类虚函数的指针。每个对象都有一个指向其类的虚函数表的指针(VPointer)。

示例:复杂继承结构中的虚函数

#include <iostream>

class Animal {
public:
    virtual void sound() {
        std::cout << "Some generic animal sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void sound() override {
        std::cout << "Bark" << std::endl;
    }
};

class Cat : public Animal {
public:
    void sound() override {
        std::cout << "Meow" << std::endl;
    }
};

void makeSound(Animal* animal) {
    animal->sound();
}

int main() {
    Dog dog;
    Cat cat;

    makeSound(&dog); // 输出 "Bark"
    makeSound(&cat); // 输出 "Meow"

    return 0;
}

输出:

Bark
Meow

总结

  • 虚函数:使用virtual关键字声明,在运行时决定调用哪个函数,实现多态。
  • 纯虚函数和抽象类:纯虚函数用于定义接口,包含纯虚函数的类称为抽象类,不能实例化。
  • 虚析构函数:在使用多态时,基类的析构函数应声明为虚函数,以确保正确调用派生类的析构函数。
  • 虚函数表(VTable):虚函数的实现依赖于虚函数表,表中存储了指向虚函数的指针。

虚函数是C++中实现多态的重要机制,通过这些示例,可以了解虚函数的基本用法及其作用。合理使用虚函数可以使代码更加灵活和可扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值