精华内容
下载资源
问答
  • 纯虚函数

    2020-11-26 01:32:42
    纯虚函数 在基类中仅仅给出声明,不对虚函数实现定义,而是在派生类中实现。这个虚函数称为纯虚函数。普通函数如果仅仅给出它的声明而没有实现它的函数体,这是编译不过的。纯虚函数没有函数体,纯虚函数需要在...

    纯虚函数


    1. 在基类中仅仅给出声明,不对虚函数实现定义,而是在派生类中实现。这个虚函数称为纯虚函数。普通函数如果仅仅给出它的声明而没有实现它的函数体,这是编译不过的。纯虚函数没有函数体,纯虚函数需要在声明之后加个=0;

    1. 定义格式 :
    class <基类名>
    {
    
    	virtual <类型><函数名>(<参数表>)=0; 
    	......
    	
    };
    
    
    1. 存在纯虚函数的类我们称为抽象类

      1. 含有纯虚函数的类被称为抽象类。抽象类只能作为派生类的基类,不能定义对象,但可以定义指针。在派生类实现该纯虚函数后,定义抽象类对象的指针,并指向或引用子类对象。

      2. 在定义纯虚函数时,不能定义虚函数的实现部分;

      3. 在没有重新定义这种纯虚函数之前,是不能调用这种函数的。

      4. 抽象类的唯一用途是为派生类提供基类,纯虚函数的作用是作为派生类中的成员函数的基础,并实现动态多态性。继承于抽象类的派生类如果不能实现基类中所有的纯虚函数,那么这个派生类也就成了抽象类。因为它继承了基类的抽象函数,只要含有纯虚函数的类就是抽象类。纯虚函数已经在抽象类中定义了这个方法的声明,其它类中只能按照这个接口去实现。

    2. 接口和抽象类的区别

      1. C++中我们一般说的接口,表示对外提供的方法,提供给外部调用。是沟通外部跟内部的桥梁。也是以类的形式提供的,但一般该类只具有成员函数,不具有数据成员;

      2. 抽象类可以既包含数据成员又包含方法。


    抽象类的实例

    1. 抽象类IShape作为基类:只有头文件,没有实现文件
    	
    	#ifndef SHAPE_H
    
    	#define SHAPE_H
    
    	#include
    
    	using std::string;
    
    	//interface
    
    	class IShape
    
    	{
    
    		public:
    	
    		virtual float getArea()=0; //纯虚函数,获得面积
    	
    		virtual string getName()=0; //纯虚函数,返回图形的名称
    
    	};
    
    	#endif
    
    	2.派生类Circle类继承自抽象类IShape:
    
    	Circle.h头文件:
    
    	#ifndef CIRCLE_H
    
    	#define CIRCLE_H
    
    	#include"Shape.h"
    
    	class CCircle : public IShape //公有继承自IShape类
    
    	{
    
    		public:
    	
    		CCircle(float radius); //构造函数
    	
    		public:
    	
    		virtual float getArea(); //实现声明实现两个基类的函数,声明的时候需要加virtual关键字,实现的时候就不需要加virtual关键字了。
    	
    		virtual string getName();
    	
    		private:
    	
    		float m_fRadius; //派生类可以拥有自己的成员
    
    	};
    
    	#endif
    
    
    	Circle.cpp实现文件:
    
    	#include"Circle.h"
    
    	CCircle::CCircle(float radius)
    
    	:m_fRadius(radius) //使用构造函数的初始化列表初始化
    	{
    	}
    
    	float CCircle::getArea() / /实现实现两个基类的函数
    
    	virtual string getName();
    	{
    		return 3.14 * m_fRadius * m_fRadius;
    	}
    
    	string CCircle::getName()
    
    	{
    
    		return "CCircle";
    
    	}
    
    
    	3. 派生类Rect类继承自抽象类IShape:
    
    	Rect.h头文件:
    
    	#ifndef RECT_H
    
    	#define RECT_H
    
    	#include"shape.h"
    
    	class CRect : public IShape
    
    	{
    
    		public:
    	
    		CRect(float nWidth, float nHeight);
    	
    		public:
    	
    		virtual float getArea();
    	
    		virtual string getName();
    	
    		private:
    	
    		float m_fWidth; //矩形类具有自己的两个属性,宽和高
    	
    		float m_fHeight;
    
    	};
    
    	Rect.cpp实现文件:
    
    	#include"Rect.h"
    
    	CRect::CRect(float fWidth, float fHeight)
    
    	:m_fWidth(fWidth), m_fHeight(fHeight)
    
    	{
    
    	}
    
    	float CRect::getArea()
    
    	{
    
    		return m_fWidth * m_fHeight;
    
    	}
    
    	string CRect::getName()
    
    	{
    
    		return "CRect";
    
    	}
    
    
    	4.测试文件main.cpp:
    
    	#include
    
    	#include"Rect.h"
    
    	#include"Circle.h"
    
    	using namespace std;
    
    	int main()
    
    	{
    
    		IShape* pShape = NULL; //定义了一个抽象类的指针,注意抽象类不能定义对象但是可以定义指针
    		
    		pShape = new CCircle(20.2); //基类指针指向派生类的对象
    	
    		cout<getName()<<" "<getArea()<<endl;
    	
    		delete pShape; //释放了CCirle对象所占的内存,但是指针是没有消失的,它现在就是一个野指针,我们在使用之前必须对它赋值
    	
    		pShape = new CRect(20, 10); //基类指针指向派生类的对象
    	
    		cout<getName()<<" "<getArea()<<endl;
    	
    		return 0;
    
    	}
    	
    

    运行结果如下:可以看到,我们使用父类的指针调用同一个函数,分别调用了这两个派生类的对应函数,
    它根据指针指向的类型的不同来决定调用的方法。即使我们以后需要新增加几个类,我们还是这种调用方法,这就是多态的巨大魅力。

    展开全文
  • 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的...定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

    http://blog.csdn.net/hackbuteer1/article/details/7558868

    首先:强调一个概念

    定义一个函数为虚函数,不代表函数为不被实现的函数。
    定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
    定义一个函数为纯虚函数,才代表函数没有被实现。

    定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。
    1、简介
    假设我们有下面的类层次:
    1. class A
    2. {
    3. public:
    4. virtual void foo()
    5. {
    6. cout<<"A::foo() is called"<<endl;
    7. }
    8. };
    9. class B:public A
    10. {
    11. public:
    12. void foo()
    13. {
    14. cout<<"B::foo() is called"<<endl;
    15. }
    16. };
    17. int main(void)
    18. {
    19. A *a = new B();
    20. a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!
    21. return 0;
    22. }
    class A
    {
    public:
        virtual void foo()
        {
            cout<<"A::foo() is called"<<endl;
        }
    };
    class B:public A
    {
    public:
        void foo()
        {
            cout<<"B::foo() is called"<<endl;
        }
    };
    int main(void)
    {
        A *a = new B();
        a->foo();   // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!
        return 0;
    }
    这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。
    虚函数只能借助于指针或者引用来达到多态的效果。

    C++纯虚函数
    一、定义
     纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
     virtual void funtion1()=0
    二、引入原因
      1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
      2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
      为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。

    声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。
    纯虚函数最显著的特征是:它们必须在继承类中重新声明函数(不要后面的=0,否则该派生类也不能实例化),而且它们在抽象类中往往没有定义。
    定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
    纯虚函数的意义,让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。


    抽象类的介绍
    抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。
    (1)抽象类的定义: 称带有纯虚函数的类为抽象类。
    (2)抽象类的作用:
    抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。
    (3)使用抽象类时注意:

    • 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。
    • 抽象类是不能定义对象的。


    总结:

    1、纯虚函数声明如下: virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。
    2、虚函数声明如下:virtual ReturnType FunctionName(Parameter);虚函数必须实现,如果不实现,编译器将报错,错误提示为:
    error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
    3、对于虚函数来说,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。
    4、实现了纯虚函数的子类,该纯虚函数在子类中就编程了虚函数,子类的子类即孙子类可以覆盖该虚函数,由多态方式调用的时候动态绑定。
    5、虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。
    6、在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。
    7、友元不是成员函数,只有成员函数才可以是虚拟的,因此友元不能是虚拟函数。但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。
    8、析构函数应当是虚函数,将调用相应对象类型的析构函数,因此,如果指针指向的是子类对象,将调用子类的析构函数,然后自动调用基类的析构函数。

    有纯虚函数的类是抽象类,不能生成对象,只能派生。他派生的类的纯虚函数没有被改写,那么,它的派生类还是个抽象类。
    定义纯虚函数就是为了让基类不可实例化化
    因为实例化这样的抽象数据结构本身并没有意义。
    或者给出实现也没有意义
    实际上我个人认为纯虚函数的引入,是出于两个目的
    1、为了安全,因为避免任何需要明确但是因为不小心而导致的未知的结果,提醒子类去做应做的实现。
    2、为了效率,不是程序执行的效率,而是为了编码的效率。
    展开全文
  • 一、纯虚函数定义 纯虚函数是一种特殊的虚函数,它的一般格式如下: class <类名> { virtual <类型><函数名>(<参数表>)=0; … }; 在许多情况下,在基类中不能对虚函数给出有意义的...

    一、纯虚函数定义

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

    class <类名>

    {

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

    };

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

    纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。

    这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

    二、纯虚函数引入原因

    1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。

    2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔 雀等子类,但动物本身生成对象明显不合常理。

    为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;)。

    若要使派生类为非抽象类,则编译器要求在派生类中,必须对纯虚函数予以重载以实现多态性。同时含有纯虚函数的类称为抽象类,它不能生成对象。

    这样就很好地解决了上述两个问题。

    例如,绘画程序中,shape作为一个基类可以派生出圆形、矩形、正方形、梯形等, 如果我要求面积总和的话,那么会可以使用一个 shape * 的数组,只要依次调用派生类的area()函数了。

    如果不用接口就没法定义成数组,因为既可以是circle ,也可以是square ,而且以后可能加上rectangle,等等.

    三、相似概念

    1、多态性

    指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。

    a.编译时多态性:通过重载函数实现

    b 运行时多态性:通过虚函数实现。

    2、虚函数

    虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载

    3、抽象类

    包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。

     

     

    另外如果你想更好的提升你的编程能力,学好C语言C++编程!弯道超车,快人一步!笔者这里或许可以帮到你~

    UP在主页上传了一些学习C/C++编程的视频教程,有兴趣或者正在学习的小伙伴一定要去看一看哦!会对你有帮助的~

    分享(源码、项目实战视频、项目笔记,基础入门教程)

    欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

    编程学习书籍:

    编程学习资料:

     

    展开全文
  • 1.虚函数(impure virtual)C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。...2.纯虚函数(pure virtual)C++中包含纯虚函数的类,被称为是“抽象类”。抽象...

    1.虚函数(impure virtual)

    C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。

    子类可以重写父类的虚函数实现子类的特殊化。

    如下就是一个父类中的虚函数:

    copycode.gifclass A

    {

    public:

    virtual void out2(string s)

    {

    cout<

    }

    };

    copycode.gif

    2.纯虚函数(pure virtual)

    C++中包含纯虚函数的类,被称为是“抽象类”。抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象。

    C++中的纯虚函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。

    C++中的纯虚函数也是一种“运行时多态”。

    如下面的类包含纯虚函数,就是“抽象类”:

    copycode.gifclass A

    {

    public:

    virtual void out1(string s)=0;

    virtual void out2(string s)

    {

    cout<

    }

    };

    copycode.gif

    3.普通函数(no-virtual)

    普通函数是静态编译的,没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。

    普通函数是父类为子类提供的“强制实现”。

    因此,在继承关系中,子类不应该重写父类的普通函数,因为函数的调用至于类对象的字面值有关。

    4.程序综合实例

    copycode.gif#include using namespace std;class A

    {

    public:

    virtual void out1()=0;  ///由子类实现

    virtual ~A(){};

    virtual void out2() ///默认实现

    {

    cout<

    }

    void out3() ///强制实现

    {

    cout<

    }

    };

    class B:public A

    {

    public:

    virtual ~B(){};

    void out1()

    {

    cout<

    }

    void out2()

    {

    cout<

    }

    void out3()

    {

    cout<

    }

    };

    int main()

    {

    A *ab=new B;

    ab->out1();

    ab->out2();

    ab->out3();

    cout<

    B *bb=new B;

    bb->out1();

    bb->out2();

    bb->out3();

    delete ab;

    delete bb;

    return 0;

    }

    copycode.gif

    执行结果:

    262307107295135.x-png

    展开全文
  • 虚函数与纯虚函数

    2019-09-16 21:48:39
    虚函数 定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新...纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类...
  • 理解虚函数( virtual function )的几个关键点: 理解早绑定(early binding)、晚绑定(late binding)。所谓early binding:On compile time,就能明确一个函数调用是对哪个对象的哪个成员函数进行的,即编译时就晓得...
  • 虚函数和纯虚函数的区别

    万次阅读 多人点赞 2012-05-11 22:35:51
    首先:强调一个概念 ...定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。 1、简介 假设我们有下面的类层次: class A { public:  virtual void foo
  • 虚函数和纯虚函数

    2021-09-27 15:17:42
    定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。 //exp: class A { public: virtural void foo() { cout<<"A::fool() is caller"<<endl; } }; ...
  • c++纯虚函数

    2018-04-08 22:16:52
    纯虚函数声明: virtual 函数类型 函数名 (参数表列) = 0;纯虚函数:1.没有函数体;2.最后面的“=0”告诉编译系统“这是虚函数”; 3.是一个声明语句,最后有分号;4.纯虚函数只有函数名而不具备函数的功能,不...
  • c++纯虚函数与虚函数

    2020-01-09 13:09:16
    定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。 纯虚函数 纯虚函数形为 virtual void run() = 0; 纯虚函数在基类中是一定没有定义的 只会在基类中声明,并且...
  • 包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。 2、虚函数声明如下:virtual ReturnType FunctionName(Parameter);虚函数必须实现,如果不实现,编译器将报错...
  • c++ 纯虚函数

    2016-01-22 16:25:25
    纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数 的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。 2.虚函数声明如下:virtual ReturnType ...
  • C++之纯虚函数

    2020-04-03 17:20:45
    C++没有接口类,它通过使用纯虚函数来生成抽象类。抽象类可以作为接口的集合,实现了接口类的功能。 C++中含有纯虚函数的类叫做抽象类,顾名思义,它本身就是行为抽象的集合,因此它只描述了有这个行为,但是并未...
  • 抽象类和纯虚函数

    2019-09-21 21:41:41
    抽象类的定义就是,含有纯虚函数的类。纯虚函数跟一般的虚函数有很大不同。我们下面来了解下纯虚函数。 一.纯虚函数 即使有的虚函数在基类中不需要做任何工作,我们也要写出一个空的函数体,这时这个函数体没有...
  • 纯虚函数与抽象类

    2021-06-19 19:34:31
    title: 纯虚函数与抽象类 date: 2021-06-19 16:56:53 tags: [C++] 纯虚函数与抽象类 纯虚函数与抽象类 纯虚函数:用 virtual 声明且赋值 0 的没有函数体的函数。 抽象类:包含纯虚函数的类。 抽象类的使用 抽象...
  • 纯虚函数与抽象基类

    2017-09-11 15:14:17
    纯虚函数:C++中可以定义这样一类函数,这样的函数可以没有实现。我们把这样的函数称为纯虚函数纯虚函数有什么意义  通过它可以指明一个虚拟函数只是提供了一个可被子类型改写的接口。 纯虚函数是在基类中声明...
  • 纯虚函数和抽象类

    2019-12-08 16:20:28
    1、什么是纯虚函数、什么是抽象类? 没有函数体的虚函数的纯虚函数。包含纯虚函数的类叫抽象类。 //举栗子: class A { private: int a; public: virtual void Print( ) = 0 ;//纯虚函数 void fun() { ...
  • 纯虚函数和虚函数都是使用virtual关键字,只是纯虚函数在函数原型后面加上“=0”。 含有纯虚函数的类是抽象类,不能实例化/生成对象,只能派生,它派生的类的纯虚函数如果没有重写,那么,它的派生类也是抽象类。...
  • C++ 虚函数与纯虚函数 浅析

    千次阅读 2015-07-25 22:06:08
    在虚函数与纯虚函数的学习中,要求理解虚函数与纯虚函数的定义,了解虚函数与纯虚函数在实例化上的差异,掌握两者在实现上的必要性,熟悉纯虚函数在子类与孙类的函数类型。本文即针对上述问题展开阐述。
  • 纯虚函数和虚函数

    2015-07-01 14:54:21
    在Java、C#中有关键词abstract指明抽象函数、抽象类,但是在C++中没有这个关键词,很显然,在C++也会需要只需要在基类声明某函数的情况,而不需要写具体的实现,那C++中是如何实现这一功能的,答案是纯虚函数。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,023
精华内容 7,609
关键字:

纯虚函数引用