C++虚函数 纯虚函数 与多态的模糊解释

本文介绍了C++中虚函数的概念及其实现多态性的关键作用。通过具体实例展示了如何利用虚函数实现多态,并解释了纯虚函数与抽象类的概念。适合初学者了解C++面向对象编程中的重要特性。

//虚函数是多态的关键 virtual 我们直接定义对象 来调用函数并不能实现多态性
//多态的特性是 父类的指针可以指向子类的对象 我们可以令父类的指针指向 不同的子类对象MFC类库就是多态的原理
//比如下面我们如果同时让p1 p2分别指向新开辟的 A B类的对象 那么 调用print函数的时候就会出现都调用的基类的函数
//如何解决这个问题 呢? 那么就要用到虚函数了 我们解决的关键是将 基类的成员函数声明为虚函数 那么就可以实现多态

#include <iostream>
using namespace std ;
class A
{
public :
virtual void print()
{
cout<<"this is A "<<endl;
}
};
class B :public A
{
public :
void print()
{
cout<<"this is B"<<endl;
}
};
int main()
{
A * p1=new A ;
A * p2=new B;
p1->print() ;
p2->print() ;
return 0;
}

//多态的另一个作用就是纯虚函数
//纯虚函数 只要一个类中有 类似 virtual void a() =0 ;
//包含一个纯虚函数的类就叫抽象类 抽象类不能实现对象 只能作为接口使用 。和java的借口 类似
//在子类中如果想要实现对象 必须要实现 抽象类中的 纯虚函数
#include <iostream>
using namespace std ;
class Animal
{
public :
virtual void Language() =0;
};
class Dog :public Animal
{
public :
void Language()
{
cout<<"wang wang.."<<endl;
}
};
void main()
{
Dog dog ;
dog.Language() ;


}

<think>好的,用户之前已经问过虚函数不能是静态成员函数,现在又问“虚函数有哪些”,看起来可能想了解虚函数的更多信息。需要先确认用户的具体需求。 用户的问题有点模糊,“有哪些”可能指虚函数的类型,比如普通虚函数纯虚函数,或者虚函数的使用场景,或者是虚函数相关的其他概念,比如虚析构函数、覆盖等。也有可能用户是想问虚函数有哪些特性或用途。 首先,考虑到用户之前的问题是关于静态成员函数和虚函数的关系,现在可能想扩展对虚函数的整体理解。需要覆盖虚函数的基本概念、类型、相关特性以及使用场景。 接下来,需要确保回答结构清晰,分点说明。可能需要包括虚函数的定义、纯虚函数、虚析构函数、override关键字、final关键字,以及虚函数表等底层机制。同时,要注意使用用户之前接受的格式,比如分步骤分析,关键点总结,代码示例等。 要注意用户可能对C++的面向对象概念有一定了解,但需要更深入的解释。需要避免过于技术化的术语,同时保持准确性。比如,解释纯虚函数时,要说明抽象类的作用,虚析构函数的必要性,以及override和final的用途。 另外,用户可能想知道虚函数在实际中的应用场景,比如多态的实现,设计模式中的使用等。需要结合例子说明,帮助用户理解。 最后,检查是否符合之前的系统级指令,比如数学公式的格式,但这里可能不太涉及数学内容。确保代码示例使用正确的语法,比如用中文注释,代码正确高亮等。 总结回答结构:定义、核心作用、分类、关键特性、底层机制、使用示例、注意事项。这样分块可以让用户逐步理解,结构清晰。</think>--- ### **虚函数的核心概念** 虚函数(Virtual Function)是C++实现**运行时多态**的核心机制,允许子类重写(Override)父类的函数。以下是虚函数的关键分类和特性: --- ### **1. 虚函数的分类** | 类型 | 作用 | 语法示例 | |---------------------|----------------------------------------------------------------------|-----------------------------------| | **普通虚函数** | 基类定义默认实现,子类可选择性重写 | `virtual void func() { ... }` | | **纯虚函数** | 基类仅声明接口,子类必须重写(基类成为抽象类) | `virtual void func() = 0;` | | **虚析构函数** | 确保正确释放子类对象资源(多态删除对象时必须使用) | `virtual ~Base() { ... }` | --- ### **2. 虚函数的核心作用** - **动态绑定(Dynamic Binding)** 通过对象的实际类型(而非指针/引用类型)调用函数,实现多态。 ```cpp class Animal { public: virtual void speak() { cout << "Animal sound" << endl; } }; class Dog : public Animal { public: void speak() override { cout << "Woof!" << endl; } // 重写基类虚函数 }; int main() { Animal* obj = new Dog(); obj->speak(); // 输出 "Woof!"(动态绑定到Dog的speak) delete obj; } ``` - **抽象类接口设计** 纯虚函数强制子类实现特定功能,定义抽象接口: ```cpp class Shape { public: virtual double area() = 0; // 纯虚函数,Shape为抽象类 }; class Circle : public Shape { public: double area() override { return 3.14 * r * r; } // 必须实现 }; ``` --- ### **3. 虚函数的关键特性** | 特性 | 说明 | |---------------------|----------------------------------------------------------------------| | **虚函数表(vtable)** | 编译器为每个含虚函数的类生成虚表,存储虚函数地址 | | **虚表指针(vptr)** | 对象实例中隐含的指针,指向所属类的虚表 | | **override关键字** | 显式标记子类重写虚函数,增强代码可读性(C++11引入) | | **final关键字** | 禁止子类重写虚函数C++11引入) | --- ### **4. 虚函数的使用场景** 1. **多态对象操作** 通过基类指针/引用操作不同子类对象(如插件系统、GUI控件)。 2. **模板方法模式** 基类定义算法框架,子类重写具体步骤。 3. **接口隔离** 通过纯虚函数定义抽象接口,实现模块解耦。 --- ### **5. 注意事项** 1. **构造函数不能是虚函数** 对象构造时虚表尚未初始化。 2. **虚函数有额外开销** 虚表查找和间接调用会轻微影响性能(通常可忽略)。 3. **虚析构函数必要性** 若可能通过基类指针删除子类对象,基类必须声明虚析构函数: ```cpp Base* p = new Derived(); delete p; // 若Base的析构函数非虚,仅调用~Base(),导致资源泄漏 ``` --- ### **总结** 虚函数C++多态的核心,通过**动态绑定**实现灵活的对象行为。其核心形式包括普通虚函数纯虚函数和虚析构函数,结合`override`和`final`关键字可提升代码安全性。理解虚函数表和虚表指针的底层机制,有助于优化性能敏感场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值