纯虚函数
纯虚函数——精选推荐

纯虚函数纯虚函数是指被表明为不具体实现的虚拟成员函数。
它⽤于这样的情况:定义⼀个基类时,会遇到⽆法定义基类中虚函数的具体实现,其实现依赖于不同的派⽣类。
纯虚函数定义格式virtual 返回值类型函数名(参数表)= 0含有纯虚函数的基类是不可以定义对象的。
纯虚函数⽆实现部分,不能产⽣对象,所以含有虚函数的类是抽象类。
//Test1.h#include<iostream>using namespace std;class Fish{public:virtual void water() = 0;virtual void eat() = 0;};class Shark : public Fish{public:void water();void eat();};void Shark::eat(){cout<<"Shark eat. "<<endl;}void Shark::water(){cout<<"Shark water. "<<endl;}void fun(Fish *f){f->eat();f->water();}纯虚函数需要注意1.定义纯虚函数时,不能定义纯虚函数的实现部分。
即使是函数体为空也不可以,函数体为空就可以执⾏,只是什么也不做就返回。
⽽纯虚函数不能调⽤。
(其实可以写纯虚函数的实现部分,编译器也可以通过,但是永远也⽆法调⽤。
因为其为抽象类,不能产⽣⾃⼰的对象,⽽且⼦类中⼀定会重写纯虚函数,因此该类的虚表内函数⼀定会被替换掉,所以可以说永远也调⽤不到纯虚函数本⾝)2."=0"表明程序将不定义该函数,函数声明是为派⽣类保留⼀个位置。
“=0”的本质是将指向函数体的指针定为NULL。
3.在派⽣类中必须有重新定义的纯虚函数的函数体,这样的派⽣类才能⽤来定义对象。
(如果不重写进⾏覆盖,程序会报错)//Test.cpp#include"Test1.h"void main(){Shark s;Fish *f = &s;fun(f);}虚表和运⾏结果。
C++基抽象类的构造析构(纯)虚函数

C++基抽象类的构造析构(纯)虚函数⼀、析构函数可定义为⼀、析构函数可定义为纯虚函数纯虚函数,但也必须给出函数定义,但也必须给出函数定义 Effective C++ 条歀07: 为多态基类声明virtual 析构函数(Declare destructors virtual in polymorphic base classes ) 在某些类⾥声明纯虚析构函数很⽅便。
纯虚函数将产⽣抽象类——不能实例化的类(即不能创建此类型的对象)。
有些时候,你想使⼀个类成为抽象类,但刚好⼜没有任何纯虚函数。
怎么办?因为抽象类是准备被⽤做基类的,基类必须要有⼀个虚析构函数,纯虚函数会产⽣抽象类,所以⽅法很简单:在想要成为抽象类的类⾥声明⼀个纯虚析构函数。
1 //这⾥是⼀个例⼦:2 class awov {3 public :4 virtual ~awov() = 0; // 声明⼀个纯虚析构函数5 }; 这个类有⼀个纯虚函数,所以它是抽象的,⽽且它有⼀个虚析构函数,所以不会产⽣析构函数问题。
但这⾥还有⼀件事:必须提供纯虚析构函数的定义: awov::~awov() { ... } // 纯虚析构函数的定义 这个定义是必需的,因为虚析构函数⼯作的⽅式是:最底层的派⽣类的析构函数最先被调⽤,然后各个基类的析构函数被调⽤。
这就是说,即使是抽象类,编译器也要产⽣对~awov 的调⽤,所以要保证为它提供函数体。
如果不这么做,链接器就会检测出来,最后还是得回去把它添上。
⼆、? 关于C++为什么不⽀持虚拟构造函数,Bjarne 很早以前就在C++Style and Technique FAQ ⾥⾯做过回答 Avirtual call is a mechanism to get work done given partialinformation. In particular, "virtual" allows us to call afunction knowing only an interfaces and not the exact type of theobject. To create an object you need complete information.Inparticular, you need to know the exact type of what you want tocreate. Consequently, a "call to a constructor" cannot bevirtual. 含义⼤概是这样的:虚函数调⽤是在部分信息下完成⼯作的机制,允许我们只知道接⼝⽽不知道对象的确切类型。
虚函数以及纯虚函数

虚函数以及纯虚函数 多态性是将接⼝与实现进⾏分离;⽤形象的语⾔来解释就是实现以共同的⽅法,但因个体差异,⽽采⽤不同的策略。
虚函数和纯虚函数都是实现多态的重要⽅法。
本⽂就这两种⽅法进⾏分析以及⽐较1、虚函数在基类中声明为virtual并在⼀个或者多个派⽣类被重新定义的成员函数语法规则:virtual 函数返回类型函数名(参数表) {函数体}语法分析:虚函数的声明和定义和普通的成员函数⼀样,只是在返回值之前加⼊了关键字virtual。
在基类当中定义了虚函数,可以再⼦类中定义和基类中相同函数名、相同参数、相同返回值和不同实现体的虚函数 定义为虚函数是为了让基类函数的指针或者引⽤来指向⼦类。
#include<iostream>using namespace std;class A{public:void fun(){cout << "A::fun()..." << endl;}};class B :public A{public:void fun(){cout << "B::fun()...." << endl;}};int main(){A *a = new A; //A类指针指向A类对象a->fun();A *b = new B; //A类指针指向B类对象b->fun();delete a;delete b;return0;}分析代码:在上述代码中B为A的派⽣类,A *b=new B 是将基类的指针指向B 类对象。
输出为:显然程序没有实现我们想要的输出#include<iostream>using namespace std;class A{public:virtual void fun(){cout << "A::fun()..." << endl;}};class B :public A{public:void fun(){cout << "B::fun()...." << endl;}};int main(){A *a = new A; //A类指针指向A类对象a->fun();A *b = new B; //A类指针指向B类对象b->fun();delete a;delete b;return0;}分析:可以看出利⽤虚函数可以实现多态,也就是说实现了通过不同对象的接⼝实现了不同的功能。
C++中的纯虚函数

C++中的纯虚函数---恢复内容开始---在C++中的⼀种函数申明被称之为:纯虚函数(pure virtual function).它的申明格式如下class CShape{public:virtual void Show()=0;};在什么情况下使⽤纯虚函数(pure vitrual function)?1,当想在基类中抽象出⼀个⽅法,且该基类只做能被继承,⽽不能被实例化;2,这个⽅法必须在派⽣类(derived class)中被实现;如果满⾜以上两点,可以考虑将该⽅法申明为纯虚函数(pure virtual function).#include <iostream>#include <cstdlib>#include <cstdio>using namespace std;class abstractcls{public:abstractcls(float speed,int total) //构造函数{this->speed = speed;this->total = total;}virtual void showmember()= 0; //纯虚函数的定义protected:float speed;int total;};class car : public abstractcls{public:car(int aird,float speed,int total):abstractcls(speed,total){this->aird = aird;}virtual void showmember(){cout << speed <<"--------" <<total <<"-----------"<<aird<<endl;}protected:int aird;};int main(){car b(250,150,4);b.showmember();return0;}下⾯我们看⼀道某公司的⾯试的笔试题(含⾦量到底有多少??)#include <iostream>#include <cstdio>using namespace std;class A{public:void foo(){printf("1\n");}virtual void fuu(){printf("2\n");}};class B:public A{public :void foo(){printf("3\n");}void fuu(){printf("4\n");}};int main(){A a;B b;A *p = &a;cout<< "p->foo()---" ; p->foo() ;cout<<"p->fuu()---";p->fuu();cout <<"-------向上转型-----------"<<endl;p=&b;cout<<"p->foo()---";p->foo();cout<<"p->fuu()---";p->fuu();cout <<"--------向下转型----------"<<endl;B *ptr =(B *)&a;cout<<"ptr->foo()----";ptr->foo();cout<<"ptr->fuu()-----";ptr->fuu();return0;}先不要看答案,看⾃⼰能否作对??下⾯进⾏详细分析⼀下为什么结果是这样的??你全做对了没??第⼀个p->foo()和p->fuu()都很好理解,本⾝是基类指针,指向的⼜是基类对象,调⽤的都是基类本⾝的函数,因此输出结果就是1、2。
虚函数和纯虚函数的作用与区别

class A{
protected:
void foo();//普通类函数
virtual void foo1();//虚函数
virtual void foo2() = 0;//纯虚函数
}
观点二:
虚函数在子类里面也可以不重载的;但纯虚必须在子类去实现,这就像Java的接口一样。通常我们把很多函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为你很难预料到父类里面的这个函数不在子类里面不去修改它的实现
虚函数和纯虚函数的作用与区别
虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数!
纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!
虚函数
引入原因:为了方便使用多态特性,我们常常需要在基类中定义虚函数。
class Cman
{
public:
virtual void Eat(){……};
void Move();
private:
};
class CChild : public CMan
{
public:
virtual void Eat(){……};
private:
};
CMan m_man;
CChild m_child;
//这才是使用的精髓,如果不定义基类的指针去使用,没有太大的意义
//建筑公司就可以按照你的方法去实现了,如果你不说清楚这些,可能建筑
//公司不太了解你需要楼房的特性。用纯需函数就可以很好的分工合作了
虚函数和纯虚函数区别
virtualfree函数的详细用法

虚函数是C++中的一个非常重要的概念,它允许我们在派生类中重新定义基类中的函数,从而实现多态性。
在本文中,我们将深入探讨virtual关键字的作用,以及virtual函数和纯虚函数的使用方法。
在C++中,virtual关键字用于声明一个虚函数。
这意味着当派生类对象调用该函数时,将会调用其在派生类中的定义,而不是基类中的定义。
这种行为使得我们能够在派生类中定制化地实现函数的逻辑,从而实现不同对象的不同行为。
对于virtual函数,我们需要注意以下几点:1. 在基类中声明函数时,使用virtual关键字进行声明。
2. 派生类中可以选择性地使用virtual关键字进行重声明,但通常最好也使用virtual,以便明确表明这是一个虚函数。
3. 当使用派生类对象调用虚函数时,将会根据对象的实际类型调用适当的函数实现。
4. 虚函数的实现通过虚函数表(vtable)来实现,这是一张函数指针表,用于存储各个虚函数的位置区域。
除了普通的虚函数外,C++还提供了纯虚函数的概念。
纯虚函数是在基类中声明的虚函数,它没有函数体,只有声明。
这意味着基类不能直接实例化,只能用作其他类的基类。
纯虚函数通常用于定义一个接口,而具体的实现则留给派生类。
接下来,让我们以一个简单的例子来说明虚函数和纯虚函数的用法。
假设我们有一个基类Shape,它包含一个纯虚函数calcArea用于计算面积。
有两个派生类Circle和Rectangle,它们分别实现了calcArea 函数来计算圆形和矩形的面积。
在这个例子中,我们可以看到基类Shape定义了一个纯虚函数calcArea,它没有函数体。
而派生类Circle和Rectangle分别实现了这个函数来计算不同形状的面积。
当我们使用Shape指针指向Circle或Rectangle对象时,调用calcArea函数将会根据对象的实际类型来调用适当的实现。
除了虚函数和纯虚函数外,C++中还有虚析构函数的概念。
纯虚函数 空函数

纯虚函数空函数一、纯虚函数纯虚函数是指在基类中声明但没有定义的虚函数,它的作用是为派生类提供一个接口,派生类必须实现这个函数。
纯虚函数的声明语法为:virtual 返回类型函数名(参数列表) =0;其中“=0”表示该函数为纯虚函数。
纯虚函数的特点:1.没有函数体。
在基类中声明但没有提供函数的具体实现,从而使得基类成为了抽象类,不能被实例化。
2.继承。
子类必须实现纯虚函数,否则也将成为抽象类,无法被实例化。
3.多态性。
子类中实现了基类的纯虚函数后,可以通过基类指针调用子类的实现。
1.抽象类。
基类中有至少一个纯虚函数时,该基类就成为了抽象类。
抽象类不能被实例化,只能被其他类继承和实现。
2.接口。
纯虚函数提供了一种接口,规定了子类必须实现的方法。
这种方法被称为“接口”。
让我们创建一个基类Figure,定义一个纯虚函数area(),用于计算图形的面积。
代码如下:class Figure{public:virtual double area() = 0;};class Circle : public Figure{public:Circle(double r){radius = r;}double area(){return 3.1415926 * radius * radius; // 计算圆的面积}private:double radius;};使用上述代码创建一个程序,可以通过基类指针调用子类实现的结果。
代码如下:以上程序会输出圆的面积,结果如下:Circle's area is:314.15926二、空函数空函数是指没有任何实际功能的函数,用于占位或在后续开发中替换为有用的函数。
空函数的定义语法为:void 函数名(){}1.通常没有函数体,函数体中只有一个空语句,表示不需要执行任何操作。
2.占位。
空函数可以用作占位函数来占据函数列表中的某些位置,等待日后补充功能。
3.代码兼容性。
空函数可以提高代码的兼容性,当代码需要调用某个函数时,即使函数还未完成,也可以使用空函数来代替。
纯虚函数重载

纯虚函数重载
纯虚函数是C++中的一个非常重要的概念,它是一个没有实现的虚函数,需要子类进行重载。
但是,在某些情况下,我们可能需要在子类中重载一个已经定义为纯虚函数的函数。
这个过程就被称为纯虚函数重载。
纯虚函数重载的语法与普通函数重载类似。
我们可以在子类中定义一个与父类中纯虚函数同名但参数列表不同的函数。
这样,子类就可以在不改变原有接口的情况下,增加一些新的功能。
值得注意的是,纯虚函数重载必须保证函数名和返回值类型与父类中的纯虚函数完全一致,否则会导致编译错误。
另外,我们也可以在子类中继续定义一个纯虚函数,这样就可以将重载后的函数作为一个新的虚函数,供其他子类进行再次重载。
总之,纯虚函数重载是C++中一个非常重要的概念,可以帮助我们灵活地扩展父类的功能,同时又保持了原有的接口。
- 1 -。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<iostream>
using namespace std;
const double PI=3.1415926;
class Shape
{
public:
virtual double Area()=0;
};
class Triangle:public Shape
{
private:
double d,h;
public:
Triangle(double di,double gao)
{
d=di;
h=gao;
}
double Area()
{
cout<<"三角形面积为:";
return d*h*1/2;
}
};
class Circle:public Shape
{
private:
double r;
public:
Circle(double radius)
{
r=radius;
}
double Area()
{
cout<<"圆面积为:";
return PI*r*r;
}
};
class Ractangle:public Shape
{
private:
double a,b;
public:
Ractangle(double chang,double kuang)
{
a=chang;
b=kuang;
}
double Area()
{
cout<<"矩形面积为:";
return a*b;
}
};
void main()
{
Shape *p;
double a,b;
cout<<"请输入三角形底边和高:";
cin>>a>>b;
Triangle t(a,b);
p=&t;
cout<<p->Area()<<endl<<endl;
cout<<"请输入圆的半径:";
cin>>a;
Circle c(a);
p=&c;
cout<<p->Area()<<endl<<endl;
cout<<"请输入矩形两边长:";
cin>>a>>b;
Ractangle r(a,b);
p=&r;
cout<<p->Area()<<endl<<endl;
}。