返回首页

纯虚函数与虚函数区别?

248 2024-04-09 23:13 admin

一、纯虚函数与虚函数区别?

虚函数是在基类中作总体框架定义,定义时在函数的返回类型名前加上virtual构成。它的具体不同实现版本是在其类的派生类里实现的。

纯虚函数是在其类中连基本框架都定义不出来,所以只是用“virtual 类型名 函数名()=0;”的形式来声明基类中有这么一个函数,而它的实现则完全由基类的派生类根据不同需要来完成。

有纯虚函数的基类叫抽象类,不能被实例化(即不能生成对象),只能被继承。我的理解是:虚函数实现的具体版本中总是有通用的部分,这些通用部分可以在基类中定义,而纯虚函数则完全没有能共用的部分,完全是由派生类中不同的实现完成的

二、虚函数和纯虚函数的差别?

虚函数和纯虚函数都是C++中的概念,用于实现多态性。它们的主要区别在于:

函数是数学中的一个概念,它是一种特殊的映射,将输入值映射到输出值。函数可以看作是一种规则或算法,给定输入值,根据该规则或算法计算出唯一的输出值。

在数学中,函数通常表示为 f(x),其中 f 是函数的名称,x 是输入变量。函数可以是一元函数(一个输入变量)或多元函数(多个输入变量)。

函数的定义通常包括以下三个要素:

1. 定义域:输入值的集合。

2. 值域:输出值的集合。

3. 对应关系:将输入值映射到输出值的规则或算法。

根据对应关系的不同,函数可以分为不同的类型,如线性函数、多项式函数、三角函数、指数函数等。

在实际应用中,函数可以用于描述各种规律和关系,如物理定律、经济模型、生物模型等。通过函数,我们可以将实际问题转化为数学问题,从而更好地理解和解决这些问题。

1. 虚函数可以在基类中有默认实现,子类可以选择性地覆盖它们的实现。而纯虚函数则没有默认实现,必须在派生类中实现。

2. 虚函数可以被直接使用,也可以被子类重载以后以多态的形式调用。而纯虚函数不能被直接调用,必须在子类中实现该函数才可以使用。

3. 如果一个类中包含纯虚函数,则该类被称为抽象类,不能被实例化。而只含有虚函数的类可以被实例化。

总的来说,虚函数和纯虚函数都可以在子类中被重载,以多态的形式被调用,但纯虚函数在基类只有声明而没有定义,且只存在于抽象基类中。

三、什么是虚函数和纯虚函数,有什么区别?

虚函数与纯虚函数 在他们的子类中都可以被重写。它们的区别是:

(1)纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现的代码。 纯虚函数一般没有代码实现部分,如virtual void print() = 0; 而一般虚函数必须要有代码的实现部分,否则会出现函数未定义的错误。

virtual void print(){ printf("This is virtual function\n"); }(2)包含纯虚函数的类不能定义其对象,而包含虚函数的则可以。

四、虚函数

虚函数是面向对象程序设计中的一个重要概念,它允许基类的方法在派生类中被重写并实现多态性。在对象的继承链中,派生类可以对虚函数进行重写,使得程序在运行时根据对象的实际类型来调用适当的函数实现。

在C++语言中,通过在函数声明中使用关键字virtual来定义虚函数。虚函数通过解决运行时多态性问题,在对象的继承层次结构中起到了重要作用。

虚函数的原理

在C++中,虚函数的调用是通过虚函数表(virtual function table)来实现的。每个含有虚函数的类都会在内存中维护一个虚函数表,该表存储了虚函数的地址。当对象被创建时,会分配一个指向虚函数表的指针,称为虚函数表指针。

当通过基类指针或引用调用虚函数时,编译器会根据对象的实际类型查找虚函数表,并调用正确的实现。这种动态绑定的特性使得程序可以根据对象的实际类型来决定函数的调用。

虚函数的优点

虚函数的使用具有多种优点:

  • 实现多态性:虚函数允许基类的方法在派生类中进行重写,实现多态性。这样可以使程序更加灵活,根据对象的实际类型来选择不同的方法实现。
  • 代码复用:通过继承机制,派生类可以重用基类中定义的虚函数。这样可以减少重复的代码,提高代码的可维护性。
  • 扩展性:通过添加新的派生类并重写虚函数,可以很容易地扩展系统功能而不影响其他已有代码。

虚函数的注意事项

在使用虚函数时,需要注意以下几点:

  • 虚函数不能是静态成员函数或友元函数。因为静态函数和友元函数不依赖于具体的对象,无法实现动态绑定的特性。
  • 构造函数和析构函数可以是虚函数,但通常不建议将它们声明为虚函数。因为构造函数在对象创建时被调用,而此时虚函数表还没有被初始化。析构函数通常需要保持轻量级,避免出现性能问题。
  • 虚函数的调用会带来一定的性能开销,因为需要根据虚函数表进行查找。对于频繁调用的函数,可以考虑使用普通的非虚函数来提高性能。

实例演示

下面通过一个简单的例子来演示虚函数的使用:

#include<iostream> class Shape { public: virtual void draw() { std::cout << "Shape::draw() called" << std::endl; } }; class Circle : public Shape { public: void draw() override { std::cout << "Circle::draw() called" << std::endl; } }; class Rectangle : public Shape { public: void draw() override { std::cout << "Rectangle::draw() called" << std::endl; } }; int main() { Shape* shape1 = new Circle(); Shape* shape2 = new Rectangle(); shape1->draw(); shape2->draw(); delete shape1; delete shape2; return 0; }

运行结果:


Circle::draw() called
Rectangle::draw() called

从上述例子可以看出,通过基类指针调用虚函数时,根据对象的实际类型分别调用了相应的派生类函数实现。

总结

虚函数是C++中一种强大的特性,通过实现多态性提高了程序的灵活性、可维护性和扩展性。虽然虚函数的使用会带来一定的性能开销,但在大多数情况下,这个开销是可以接受的。在设计面向对象的程序时,合理地使用虚函数可以使程序更加清晰、简洁和可扩展。

五、虚函数和普通函数的区别?

虚函数是由指针地址中的数据类型来判断函数使用,而非虚函数则是仅仅看指针类型来调用;因此在非虚的情况下调用的是Animal类型,因为指针也是animal类型;而在虚函数的情况下调用的是fish类型的breathe().

六、实函数和虚函数的区别?

实函数(Non-virtual Function)和虚函数(Virtual Function)是面向对象编程中的两个概念,它们在继承和多态性方面有所区别。

1. 实函数(非虚函数):

   - 实函数是在基类中定义的普通成员函数,在子类中可以通过重写(覆盖)的方式进行修改或扩展,但并非必须。

   - 在运行时,实函数的调用是静态绑定的,即根据函数的声明类型,而不考虑实际对象的类型。

   - 编译器在编译时就确定调用的函数,在程序运行时效率较高。

2. 虚函数:

   - 虚函数是在基类中使用virtual关键字声明的成员函数,它可以在子类中重写(覆盖),实现多态性。

   - 在运行时,通过对象的实际类型动态绑定,根据对象的实际类型调用相应的函数实现动态多态性。

   - 虚函数通过使用基类指针或引用调用子类对象的方法,可以实现多态性,提高代码的灵活性和扩展性。

总结:

实函数和虚函数的区别在于,实函数在运行时根据函数的声明类型来确定调用的函数,而虚函数在运行时根据对象的实际类型动态绑定调用相应的函数。虚函数的使用可以实现多态性,使得子类对象可以按照基类对象的方式被操作和调用。

七、纯虚函数的定义?

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

纯虚函数

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

基本信息

中文名纯虚函数外文名pure virtual function定义一种特殊的虚函数

定义

纯虚函数是一种特殊的虚函数,它的一般格式如下:

class <类名>

{

virtual <类型><函数名>(<参数表>)=0;

};

纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

一般而言纯虚函数的函数体是缺省的,但是也可以给出纯虚函数的函数体(此时纯虚函数变为虚函数),这一点经常被人们忽视,调用纯虚函数的方法为baseclass::virtual function.

八、纯虚函数是不是空函数?

纯虚函数跟其他函数的不同之处是,其它虚函数都是把函数地址放在虚表中,调用的时候根据地址调用函数,而纯虚函数因为没有实现,虚表中第一项放的地址是_purecall这个函数,用于在非法调用的时候弹出出错信息;实际上抽象类中的纯虚函数也是可以实现的(注意不要在声明处实现,虽然vc支持)。类似这样:

但是实际在派生类调用的时候,上面声明的函数并不在虚表中,它本身也不在VBase的虚表中,VBase的虚表中放的还是_purecall这个函数。因为这种定义行为本身并不是被c++支持的。我的理解是可以像调用普通函数一样调用它,比如:输出依然是base call,但是如果你这调用(当然这是很不好的规范!)就会发现VBase的f依然是_purecall执行到f()的时候,会弹出错误提示pure virtual function call

九、虚函数或纯虚函数主要用来解决什么问题?

虚函数是用于后期动态绑定的,可以实现运行期多态。说白了就是一个函数指针,在运行的时候才确定最终要调用的目标。

纯虚函数顾名思义就是完全虚的函数,它没有绑定到任何一个实际函数上,是空的。

纯虚函数主要是用来阻止类的实例化,强制要求类的派生者必须实现该函数否则也不能实例化,相当于C#或java的abstract函数。

如果一个类中所有的函数都是纯虚函数,则该类就构成了一个接口。

十、虚函数和抽象函数有什么区别?

虚函数是有代码的并明确允许子类去覆盖,但子类也可不覆盖,就是说可以直接用,不用重写 。

抽象函数是没有代码,子类继承后一定要重写 在一个类中用虚函数: 是因为在超类中的有实际代码的方法,但明确允许子类可以作重写 而且当子类重写后,可以用子类实例超类;如果这样,超类变量调用虚函数时,执行的是子类的方法 在一个类中用抽象函数 是在写超类时不确定函数的代码,让子类去实现 抽象函数没有方法体。简单来说虚函数(Virtual)已经包含了也必须包含默认的实现,所以在派生类中可以重新实现也可以不实现这些虚函数。抽象函数(abstract)没有提供默认实现,所以在派生类中必须实现这些抽象函数。接口中的函数类似于抽象函数,也不提供默认实现,实现接口的类也必须实现这些函数。但接口可用于多继承,即,类只能从一个类继承,但可同时实现多个接口。

顶一下
(0)
0%
踩一下
(0)
0%
相关评论
我要评论
用户名: 验证码:点击我更换图片