虚函数(C++)

本文详细介绍了C++中将析构函数设置为虚函数的重要性。通过实例演示了当基类指针指向派生类对象时,若析构函数非虚,则只会调用基类的析构函数导致内存泄漏;而虚析构函数能够确保正确调用派生类的析构函数,进而调用基类的析构函数,避免内存泄漏。

析构函数设置成虚函数正是体现了C++的多态性。当基类的指针指向子类时,析构的时候,如果析构函数不是虚函数的话,这样只会调用基类的析构函数。子类则不会被析构,这样就造成了内存泄露。如果定义成虚函数,那么则会先找到子类的析构函数,析构之后,再调用基类的析构函数。有些人设成虚函数是为了触发基类的析构函数,我觉得理解的不是太彻底,应该是虚函数只是为了找到子类的析构函数,而触发基类的析构函数是由子类时继承了基类才自然的就会调用基类的析构函数。


虚函数的实现。


class base
{
    public:base()
    {
        cout<<"base consttruction"<<endl;
    }
    virtual print()
    {
        cout<<"base print"<<endl;
    }
};

class child : public base
{
    public:child()
    {
        cout<<"child contruction"<<endl;
    }
    virtual print()
    {
        cout<<"child print"<<endl;
    }
};
void main()
{
    base m_b;
    child m_c;
    base * pb = &m_b;pb->print();
    pb = &m_c;pb->print();
}


运行的结果:
 
base consttruction          父类对象构造
base consttruction          先调用父类构造函数
child contruction              再调用子类构造寒素
base print                        虚函数的多态性
child print
Press any key to continue

### C++ 虚函数的概念与使用方法 #### 什么是虚函数? 在C++中,虚函数是一种支持运行时多态性的机制。通过虚函数,程序可以在运行时决定调用哪个版本的函数(基类或派生类),而不是在编译时就固定下来。这种特性使得面向对象编程更加灵活和强大[^1]。 #### 虚函数的作用 虚函数的主要作用在于实现 **动态绑定** 或者称为 **运行时多态性**。当一个基类指针指向不同的派生类对象时,调用虚函数的行为由实际的对象类型决定,而非指针本身的类型。这样可以确保即使是在不知道确切对象类型的情况下也能正确调用相应的方法[^2]。 #### 声明虚函数的方式 要声明一个虚函数,只需在基类中的函数前加上关键字 `virtual` 即可。例如: ```cpp class Base { public: virtual void display() { std::cout << "Display method of Base class." << std::endl; } }; ``` 一旦某个函数被标记为虚拟,所有的派生类都可以选择重新定义这个函数以提供特定的功能实现[^3]。 #### 示例代码展示 下面是一个简单的例子来说明如何使用虚函数及其效果: ```cpp #include <iostream> using namespace std; // 基类 class Animal { public: virtual void speak() { // 虚函数 cout << "Animal speaks..." << endl; } }; // 派生类1 class Dog : public Animal { public: void speak() override { // 重写虚函数 cout << "Dog barks!" << endl; } }; // 派生类2 class Cat : public Animal { public: void speak() override { // 重写虚函数 cout << "Cat meows!" << endl; } }; int main() { Animal* myPet1 = new Dog(); // 动态分配狗对象 Animal* myPet2 = new Cat(); // 动态分配猫对象 myPet1->speak(); // 输出:Dog barks! myPet2->speak(); // 输出:Cat meows! delete myPet1; delete myPet2; return 0; } ``` 在这个例子中可以看到尽管两个指针都是 `Animal*` 类型,但由于它们分别指向了不同种类的具体动物实例,最终调用了各自对应的 `speak()` 方法[^4]。 #### 注意事项 - 如果希望防止进一步的覆盖操作,可以从C++11起使用 `final` 关键字修饰某一层级上的虚函数。 - 对于强制要求子类必须实现某些功能的情况,则应考虑纯虚函数的设计思路。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值