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

    2020-01-09 13:09:16
    定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个...

    定义一个函数为虚函数,不代表函数为不被实现的函数。
    定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
    定义一个函数为纯虚函数,才代表函数没有被实现。
    定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

    纯虚函数

    纯虚函数形为

    virtual void run() = 0;
    

    纯虚函数在基类中是一定没有定义的 只会在基类中声明,并且要求子类一定要重写该函数不然会报错。(类似于java中的接口 ,当具体继承时要求重写所有接口中的方法)
    纯虚函数目的是为了实现“运行时多态“,实现同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
    "运行时多态"是指一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被称为“虚”函数
    一个类,只要有纯虚函数就称为抽象类,一个抽象类只能作为基类,而且不能定义抽象类的对象,但是可以定义抽象类的指针,为的是,他可以指向派生类的对象实现多态。

    虚函数

    虚函数形为

    virtual void say() ;
    

    虚函数也是为了实现“运行时多态”
    区别
    对于虚函数来说,基类可以有定义,子类可以没有定义,也就是可以不重载。
    对于纯虚函数来说,基类必须无定义,子类必须有定义,也就是子类中必须重载。
    多态例子
    下面是一个经典的使用“动态绑定/运行多态”的例子

    //头文件
    #include<iostream >
    using namespace std;
    class Animal
    { 
    private:
    	int height;
    public:
    	virtual void say()  //虚函数在基类中可以有定义
    	{
    		cout << "i am animal"<<endl;
    	}
    	virtual void run() = 0;  //纯虚函数在基类中无定义
    
     };
    
    class Cat :public Animal
    {
    private:
    	int color;
    public:
    	void say()  //重写虚函数
    	{
    		cout << "i am a cat"<<endl;
    	}
    	void run()  //必须重写纯虚函数
    	{
    		cout << "cat run" << endl;
    	}
    };
    class Dog :public Animal
    {
    private:
    	int weight;
    public:
    	void say()
    	{
    		cout << "i am a dog" <<  endl;
    	}
    	void run()
    	{
    		cout << "dog run" << endl;
    	}
    };
    class Person :public Animal
    {
    private:
    	int id;
    public:
    	void run()  //可以不重载 虚函数 但是必须重载 纯虚函数
    	{
    		cout << "person run" << endl;
    	}
    };
    
    //cpp
    #include"标头.h"
    #include<list>
    int main()
    {
    	//Animal a;
    	list<Animal *>animals;
    
    	Animal *a = new Dog();
    	Animal *b = new Cat();
    	Animal *c = new Person();
    	animals.push_back(a);
    	animals.push_back(b);
    	animals.push_back(c);
    
    	for (auto i : animals)
    	{
    		i->say();
    	}
    	for (auto i : animals)
    	{
    		i->run();
    	}
    
    //虚函数
    //i am a dog //执行子类方法
    //i am a cat //执行子类方法
    //i am animal //找不到子类方法后 执行父类方法
    
    //纯虚函数全部执行子类方法
    //dog run
    //cat run
    //person run
    
    	
    	return 0;
    }
    

    C++纯虚函数

    一、定义

    纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
     virtual void funtion1()=0

    二、引入原因

    1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
      2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
      为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。
    声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。
    纯虚函数最显著的特征是:它们必须在继承类中重新声明函数(不要后面的=0,否则该派生类也不能实例化),而且它们在抽象类中往往没有定义。
    定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
    纯虚函数的意义,让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。

    总结:

    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 CPerson { CPerson(); ~CPerson(); public: v...

    使用了纯虚函数的类为一个抽象类(个人对抽象类的理解为类中含有未进行定义的函数(纯虚函数)的类被称为抽象类),纯虚函数只能用于继承接口,实现一般在子类中需要时实现,还有很重要的一点是抽象类无法生成对象。
    有进行行为声明的纯虚函数叫虚函数(不知道这样说对不对)
    class CPerson
    {
    CPerson();
    ~CPerson();
    public:
    virtual void Move() = 0;//纯虚函数的声明为带有virtual关键字并且没有进行实际的函数行为定义,并且要将该函数初始化为0;
    virtual void Eat(){
    //函数声明部分
    }
    }
    class CMan: public CPerson
    {
    public:
    CMan();
    ~CMan();
    virtual void Move(){
    cout << “男人移动” << endl;//重载
    }
    virtual void Eat(){
    cout << “男人吃东西” << endl;
    }
    private:

    };
    CPerson *p = new CMan();//如果创建的对象
    //CPerson *p1 = new CPerson();//报错:抽象类无法进行创建对象;
    int _tmain(int argc, _TCHAR* argv[])
    {
    p->Move();//输出的是派生类的Move函数
    system(“pause”);
    return 0;
    }

    展开全文
  • 纯虚函数:在抽象类(类中包含纯虚函数)中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。如果在基类中没有保留函数名字,则无法实现多态性。 虽然抽象类不能定义对象(或者说抽象类不能实例化)...
    纯虚函数:在抽象类(类中包含纯虚函数)中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。如果在基类中没有保留函数名字,则无法实现多态性。
    虽然抽象类不能定义对象(或者说抽象类不能实例化),但是可以定义指向抽象类数据的指针变量。当派生类成为具体类之后,就可以用这种指针指向派生类对象, 然后通过该指针调用虚函数, 实现多态性的操作。

    虚函数:实现动态多态

    C++基础之多态性与虚函数

    虚继承:减少存储空间,相同的内容只存一份。

    C++基础之类的虚继承

    展开全文
  • C++纯虚函数与虚析构函数1.纯虚函数2.ADT过程3.虚析构函数 1.纯虚函数 什么是纯虚函数? 没有函数体的虚函数,如: virtual void print() = 0; 什么是抽象类? 有一个及其以上的纯虚函数的类,称之为抽象类。 //...

    C++纯虚函数与虚析构函数

    1.纯虚函数

    什么是纯虚函数?
    没有函数体的虚函数,如:

    virtual void print() = 0;
    

    什么是抽象类?
    有一个及其以上的纯虚函数的类,称之为抽象类。

    //抽象类
    class Object 
    {
    public:
    	//纯虚函数
    	virtual void print() = 0;
    protected:
    };
    

    抽象类的特点:
    不能构建对象,可以构建对象指针。
    一般拿来充当中间访问层。

    2.ADT过程

    别人写好了一个抽象类给你,就好比下发了一个任务。需要你去实现

    class List 
    {
    public:
    	//防止析构问题
    	virtual  ~List() //抽象类被继承 使用这种方式
    	{
    		cout << "list的析构函数" << endl;
    	}
    	virtual void push_back(int element) = 0;
    	virtual void push_front(int element) = 0;
    	virtual void pop_back() = 0;
    	virtual int front() = 0;
    	virtual void pop_front()=0;
    	virtual int size() const = 0;
    	virtual int empty() const = 0;
    };
    

    发给我们干嘛?又不能构建对象,没办法,我们只能去实现一下这些功能,让它可以构建对象。

    这个时候子类应该怎么写?(假装已经实现功能)

    子类的virtual可写可不写,写不写它都是虚函数。

    class arrayList:public List
    {
    public:
    	~arrayList() 
    	{
    		cout << "arrayList的析构函数" << endl;
    	}
    	virtual void push_back(int element) {}
    	virtual void push_front(int element) {}
    	virtual void pop_back() {}
    	virtual void pop_front() {}
    	virtual int front() { return 1; };
    	//常成员函数: 特性,不能数据数据成员,常对象只能调用常成员函数
    	virtual int size() const { return 0; }
    	virtual int empty()const { return 0; }
    };
    

    3.虚析构函数

    父类中我们写的是

    virtual  ~List() //抽象类被继承 使用这种方式
    	{
    		cout << "list的析构函数" << endl;
    	}
    	
    

    1.virtual 作用:实现父类指针调用子类成员
    2.虚析构函数实现非正常情况下的指针赋值导致的析构函数。父类指针被子类对象初始化,父类的析构函数必须使用虚析构函数

    多态我们怎么搞得?
    首先就是为了解决纵向重载的问题,我们把父类函数写作虚函数,实现父类指针使用子类方法。
    这里可以理解为,底层析构函数是同名的。

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

    2021-03-05 21:31:34
    虚函数的声明语句末尾中加个 =0 ,就是纯虚函数。 有纯虚函数的类就是纯虚类。
  • 本人仅用于学习参考 ...C++虚函数和纯虚函数区别 作者总结: 1.纯虚函数声明如下: virtual ReturnType FunctionName(Parameter)=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函
  • 1、在一个类中定义一个纯虚函数,则这个类是抽象类。纯虚函数在基类中是不实现的,只是提供一个接口。在子类中分别去实现。在很多情况下,类本身是不生成对象的。动物作为一个基类可以派生出老虎、孔雀等子类,但...
  • 纯虚函数虚函数都是使用virtual关键字,只是纯虚函数在函数原型后面加上“=0”。 含有纯虚函数的类是抽象类,不能实例化/生成对象,只能派生,它派生的类的纯虚函数如果没有重写,那么,它的派生类也是抽象类。...
  • 作者总结: 1.纯虚函数声明如下: virtual ReturnType FunctionName(Parameter)=0;  纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。...2.虚函数声明如下:virtual ReturnType FunctionName(P
  • 虚函数与纯虚函数区别虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!...
  • 纯虚函数与虚基类

    千次阅读 2015-02-06 22:08:15
    纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0” virtual void funtion()=0; 虚函数的定义是:virtual void ...
  • 首先纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,