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

    2015-06-23 09:45:33
    虚函数和纯虚函数

    文章系转载,慎重使用,尊重原创:
    http://www.cnblogs.com/bluestorm/archive/2012/08/29/2662350.html

    • 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。

    • 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class)只有声明而没有定义。值得注意的是,我们可以为纯虚函数提供定义,不过函数体必须定义在类的外部,也就是说,我们不能在类的内部为一个=0的函数提供函数体。

    • 虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用。

    • 虚函数和纯虚函数通常存在于抽象基类(abstract base class -ABC)之中,被继承的子类重载,目的是提供一个统一的接口。

    • 虚函数的定义形式:virtual {method body}
      纯虚函数的定义形式:virtual { } = 0;
      在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样。

    • 虚函数必须实现,如果不实现,编译器将报错,错误提示为:

    error LNK****: unresolved external symbol “public: virtual void __thiscall
    ClassName::virtualFunctionName(void)”

    • 虚函数来说,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。

    • 实现了纯虚函数的子类,该纯虚函数在子类中就编程了虚函数,子类的子类即孙子类可以覆盖,该虚函数,由多态方式调用的时候动态绑定。

    • 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数

    • 多态性指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。
      a.编译时多态性:通过重载函数实现
      b 运行时多态性:通过虚函数实现。

    • 如果一个类中含有纯虚函数,那么任何试图对该类进行实例化的语句都将导致错误的产生,因为抽象基类(ABC)是不能被直接调用的。必须被子类继承重载以后,根据要求调用其子类的方法。

    //father class
      class Virtualbase
      {
      public:
          virtual void Demon() = 0; //prue virtual function
          virtual void Base() {cout<<"this is farther class"<};
      }
    
      //sub class
      class SubVirtual :public Virtualbase
      {
      public:
          void Demon() { cout<<" this is SubVirtual!" }
          void Base() { cout<<"this is subclass Base" } 
      }
    
      /*
      instance class and sample
      */
      void main()
      {
      Virtualbase* inst = new SubVirtual(); //multstate pointer
      
      inst->Demon();
      inst->Base();
      // inst = new Virtualbase();
      // inst->Base()
      return ;
    
    }
    展开全文
  • 虚函数纯虚函数区别虚函数为了重载多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!...

    虚函数与纯虚函数区别虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数!

    纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像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;

    //这才是使用的精髓,如果不定义基类的指针去使用,没有太大的意义

    CMan *p ;

    p = &m_man ;

    p->Eat(); //始终调用CMan的Eat成员函数,不会调用 CChild 的

    p = &m_child;

    p->Eat(); //如果子类实现(覆盖)了该方法,则始终调用CChild的Eat函数

    //不会调用CMan 的 Eat 方法 ;如果子类没有实现该函数,则调用CMan的Eat函数

    p->Move(); //子类中没有该成员函数,所以调用的是基类中的

    纯虚函数

    引入原因:

         1、同“虚函数”;

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

    //纯虚函数就是基类只定义了函数体,没有实现过程定义方法如下

    // virtual void Eat() = 0; 直接=0 不要 在cpp中定义就可以了

    //纯虚函数相当于接口,不能直接实例话,需要派生类来实现函数定义

    //有的人可能在想,定义这些有什么用啊 ,我觉得很有用

    //比如你想描述一些事物的属性给别人,而自己不想去实现,就可以定

    //义为纯虚函数。说的再透彻一些。比如盖楼房,你是老板,你给建筑公司

    //描述清楚你的楼房的特性,多少层,楼顶要有个花园什么的

    //建筑公司就可以按照你的方法去实现了,如果你不说清楚这些,可能建筑

    //公司不太了解你需要楼房的特性。用纯需函数就可以很好的分工合作了

    虚函数和纯虚函数区别

    观点一:

    类里声明为虚函数的话,这个函数是实现的,哪怕是空实现,它的作用就是为了能让这个函数在它的子类里面可以被重载,这样的话,这样编译器就可以使用后期绑定来达到多态了

    纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现。

    class A{

    protected:

        void foo();//普通类函数

        virtual void foo1();//虚函数

        virtual void foo2() = 0;//纯虚函数

    }

    观点二:

    虚函数在子类里面也可以不重载的;但纯虚必须在子类去实现,这就像Java的接口一样。通常我们把很多函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为你很难预料到父类里面的这个函数不在子类里面不去修改它的实现

    观点三:

    虚函数的类用于“实作继承”,继承接口的同时也继承了父类的实现。当然我们也可以完成自己的实现。纯虚函数的类用于“介面继承”,主要用于通信协议方面。关注的是接口的统一性,实现由子类完成。一般来说,介面类中只有纯虚函数的。

    观点四:

    带纯虚函数的类叫虚基类,这种基类不能直接生成对象,而只有被继承,并重写其虚函数后,才能使用。这样的类也叫抽象类。

    虚函数是为了继承接口和默认行为

    纯虚函数只是继承接口,行为必须重新定义

    转载于:https://www.cnblogs.com/zhchongyao/archive/2010/02/23/1672143.html

    展开全文
  • C++的类要实现多态,不像java,直接就有,而是需要给...虚函数如上面所说的,加上virtual即可,因为不是纯虚函数,所以也同样需要提供函数的定义纯虚函数除了同样必须要有virtual关键字外,函数的定义不是必须的,...

    C++的类要实现多态,不像java,直接就有,而是需要给函数前面带上virtual,所以java的成员函数从c++角度来说的话都是虚函数。

    再基类指针或引用指向派生类的时候,调用虚函数,就会在运行时判断并采用真实对象的函数实现,而不是基类的。

    虚函数

    如上面所说的,加上virtual即可,因为不是纯虚函数,所以也同样需要提供函数的定义

    纯虚函数

    除了同样必须要有virtual关键字外,函数的定义不是必须的,纯虚函数就是在声明时加上=0即可,如过想要带上定义,那只能把定义放到外面。如

    class A {

    public:

    virtual void print() = 0;

    }

    void A::print() {

    cout << 123 << endl;

    }

    含有纯虚函数的类是属于抽象类,是不能用他们直接创建对象的,如果要在派生类中调用基类的方法,则采用A::print()的形式。

    析构函数(虚/纯虚?)

    在继承的情况下,对于一个派生类对象的实例,他的正常销毁是需要从派生类的析构函数开始,一直向上调用各级父类的析构函数。

    如果类中包含虚函数,那么析构函数最好也声明为虚函数,因为如果不然,在delete一个基类的指针时,就会无法调用到派生类的析构函数,就可能出现问题。

    而如果析构函数是虚函数,我们也一般不会把它定义为纯虚函数,因为和其它函数不同,编译器要求析构函数必须要有定义(而纯虚函数可以没有函数定义/函数体),这样销毁对象时才能有东西调用。如果非要定义为纯虚函数,那么需要给它提供函数定义。

    展开全文
  • C++虚函数纯虚函数和多态1.多态多态,按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的...

    C++虚函数与纯虚函数和多态

    1.多态

    多态,按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。

    多态特性是C++中重要的特性之一,在多态中,引用和指针的静态类型和动态类型可以是不同的,这是C++支持多态的基石。通过基类引用或指针调用基类中定义的函数时,我们并不知道执行函数的确切类型是什么,执行函数的类型可能是基类类型的,也可能是派生类型的。

    如果调用的是非虚函数,那么无论对象是什么类型的,都会执行基类类型所定义的函数。如果调用虚函数,则直到运行时,才能确定调用了哪个类型的函数,运行的虚函数是引用所绑定的或指针所指向的对象所属的类型定义的版本。

    从代码的角度来看,我们无需担心。只要正确的设计了类和函数,不管实际操作对象是基类类型的,还是派生类类型的,都将正确的工作。

    2.C++虚函数

    上段内容中,提到了实现多态的方式--虚函数,虚函数只是其中的一种,在C++中,除了虚函数,实现多态的方式还有抽象类,覆盖,模版等。这里详细的说下虚函数的工作方式,其他不予以说明。下面来一个比较经典的关于虚函数的例子:

    1: class A

    2: {

    3: public:

    4:     virtual void foo()

    5:     {

    6:         cout<

    7:     }

    8: };

    9: class B:public A

    10: {

    11: public:

    12:     void foo()

    13:     {

    14:         cout<

    15:     }

    16: };

    17: int main(void)

    18: {

    19:     A *a = new B();

    20:     a->foo();   // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!

    21:     return 0;

    22: }

    看了上面的代码,读者应该大概的理解了虚函数的作用,在派生类中,允许定义与基类同名的函数,即重写基类函数,也可以说是覆盖(override),并且可以通过基类指针或引用,调用基类和派生类中的同名的函数。

    3.纯虚函数

    纯虚函数,其实并无什么特别的意义。拿下面这个例子来说:

    1: class 动物 {

    2:        virtual void miao() { 这里我应该写什么? }

    3: }

    4: class 猫: 动物{  xxx }

    5: class 狗: 动物{ xxx  } 这个类是动物,我们现在需要做的是让不同的动物都要做一个发出叫声的动作。 代码中应该写什么呢?因为并没有叫“动物”这种动物,所以“动物”是没有叫声的;另外,动物* a = new 动物; // 这代表了什么 ?没有 "动物" 这种 动物,你 new 猫 或者 new 狗都可以理解,但是 new 动物 表示什么 ?所以,C++引入了一个“纯虚”的标识。

    class 动物 {

    virtual miao() = 0; // 函数后面写 =0

    }

    =0 就表示这个函数是“纯虚函数”,意思是“没有什么意义的函数”,你不需要写函数体,如果某个类, 里面有 任意一个 纯虚函数存在, 那么这个类就是 "纯虚类","纯虚类" 只有 一个 特点.那就是不能声明对象,如果你要是new对象的话,那么编译器会给你一个 error..

    对于纯虚类,C++primer 书中是这么给出的定义:

    含有(或继承)一个或多个纯虚函数的类是 抽象基类。除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象。

    关于虚函数,纯虚函数和多态就说这么多,如有错误,欢迎指正。

    展开全文
  • 定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,370
精华内容 948
关键字:

虚函数和纯虚函数