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

    2014-04-28 18:01:37
     // =0标志一个虚函数纯虚函数 };  一个函数声明为纯虚后,纯虚函数的意思是:我是一个抽象类!不要把我实例化!纯虚函数用来规范派生类的行为,实际上就是所谓的“接口”。它告诉使用者,我的派生类都会有...
    如下声明表示一个函数为纯虚函数:
    class A
    {
    public:
        virtual void foo()=0;   // =0标志一个虚函数为纯虚函数
    };

        一个函数声明为纯虚后,纯虚函数的意思是:我是一个抽象类!不要把我实例化!纯虚函数用来规范派生类的行为,实际上就是所谓的“接口”。它告诉使用者,我的派生类都会有这个函数。

    * 有纯虚函数的类是抽象类,不能生成对象,只能派生。他派生的类的纯虚函数没有被改写,那么,它的派生类还是个抽象类。

    *定义纯虚函数就是为了让基类不可实例化化,
        因为实例化这样的抽象数据结构本身并没有意义.
        或者给出实现也没有意义
        实际上纯虚函数的引入,可能是出于两个目的,
        1.为了安全.因为避免任何需要明确但是因为不小心而导致的未知的结果. 提醒子类去做应做的实现.
        2.为了效率,不是程序执行的效率,而是为了编码的效率.

    * 当一个类打算被用作其它类的基类时,它的析构函数必须是虚的

    那么,什么是虚函数呢,我们先来看看微软的解释:

    虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。

    ——摘自MSDN

    例子:
    #i nclude "stdio.h"
    #i nclude "conio.h"
    class Parent
    {
    public:
        char data[20];
        void Function1();
        virtual void Function2(); // 这里声明Function2是虚函数
    }parent;

    void Parent::Function1()
    {
        printf("This is parent,function1\n");
    }

    void Parent::Function2()
    {
        printf("This is parent,function2\n");
    }

    class Child:public Parent
    {
        void Function1();
        void Function2();
    } child;

    void Child::Function1()
    {
        printf("This is child,function1\n");
    }

    void Child::Function2()
    {
        printf("This is child,function2\n");
    }

    int main(int argc, char* argv[])
    {
        Parent *p; // 定义一个基类指针
        if(_getch()=='c') // 如果输入一个小写字母c
            p=&child; // 指向继承类对象
        else
            p=&parent; // 否则指向基类对象
        
        p->Function1(); // 这里在编译时会直接给出Parent::Function1()的入口地址。
        p->Function2(); // 注意这里,执行的是哪一个Function2?
        return 0;
    }

    用任意版本的Visual C++或Borland C++编译并运行,输入一个小写字母c,得到下面的结果:
    This is parent,function1
    This is child,function2
    为 什么会有第一行的结果呢?因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器 无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了 第一行的结果。

    那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就 是说,它是一个虚函数。虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。

    如果我们在运行上面的程序时任意输 入一个非c的字符,结果如下:
    This is parent,function1
    This is parent,function2
    展开全文
  • 纯虚函数和虚函数

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

    在Java、C#中有关键词abstract指明抽象函数、抽象类,但是在C++中没有这个关键词,很显然,在C++也会需要只需要在基类声明某函数的情况,而不需要写具体的实现,那C++中是如何实现这一功能的,答案是纯虚函数 含有纯虚函数的类是抽象类,不能生成对象,只能派生。他派生的类的纯虚函数没有被改写,那么它的派生类还是个抽象类。定义纯虚函数就是为了让基类不可实例化化意义。

    一.  纯虚函数

    在许多情况下,在基类中不能给出有意义的虚函数定义,这时可以把它说明成纯虚函数,把它的定义留给派生类来做。定义纯虚函数的一般形式为:

    class 类名{

     virtual 返回值类型 函数名(参数表)= 0;  // 后面的"= 0"是必须的,否则,就成虚函数了

    };

    纯虚函数是一个在基类中说明的虚函数,它在基类中没有定义,要求任何派生类都定义自己的版本。纯虚函数为各派生类提供一个公共界面。

    从基类继承来的纯虚函数,在派生类中仍是虚函数。

    二. 抽象类

    1. 如果一个类中至少有一个纯虚函数,那么这个类被称为抽象类(abstract class)。

    抽象类中不仅包括纯虚函数,也可包括虚函数。抽象类中的纯虚函数可能是在抽象类中定义的,也可能是从它的抽象基类中继承下来且重定义的。

    2. 抽象类特点,即抽象类必须用作派生其他类的基类,而不能用于直接创建对象实例。

    一个抽象类不可以用来创建对象,只能用来为派生类提供一个接口规范,派生类中必须重载基类中的纯虚函数,否则它仍将被看作一个抽象类。

    3. 在effective c++上中提到,纯虚函数可以被实现(定义)(既然是纯虚函数,为什么还可以被实现呢?这样做有什么好处呢?下文中“巧用纯虚析构函数实现接口类”中将说明这一功能的目的。),但是,不能创建对象实例,这也体现了抽象类的概念。

    三. 虚析构函数

    虚析构函数: 在析构函数前面加上关键字virtual进行说明,称该析构函数为虚析构函数。虽然构造函数不能被声明为虚函数,但析构函数可以被声明为虚函数

    一般来说,如果一个类中定义了虚函数, 析构函数也应该定义为虚析构函数。

    例如:

    class B

    {

     virtual ~B();  //虚析构函数

      …

    };

    下面介绍一些实例:

    1. #include <stdio.h>  
    2.   
    3. class Animal  
    4. {  
    5. public:  
    6.      Animal()   //构造函数不能被声明为虚函数  
    7.      {  
    8.     printf(" Animal construct! \n");  
    9.      }  
    10.      virtual void shout() = 0;  
    11.      virtual void impl() = 0;  
    12.      virtual ~Animal() {printf(" Animal destory! \n");};   // 虚析构函数  
    13. };  
    14.   
    15.   
    16. void Animal::impl()        // 纯虚函数也可以被实现。  
    17. {  
    18.      printf(" Animal: I can be implement! \n");  
    19. }  
    20.   
    21.   
    22. class Dog: public Animal  
    23. {  
    24. public:  
    25.      Dog()  
    26.      {  
    27.     printf(" Dog construct! \n");  
    28.      }  
    29.      virtual void shout() // 必须要被实现,即使函数体是空的  
    30.      {  
    31.          printf(" Dog: wang! wang! wang! \n");  
    32.      }  
    33.      virtual void impl()  
    34.      {  
    35.          printf(" Dog: implement of Dog!  \n");  
    36.      }  
    37.      virtual ~Dog() {printf(" Dog destory! \n");};   // 虚析构函数  
    38. };  
    39.   
    40.   
    41. class Cat: public Animal  
    42. {  
    43. public:  
    44.      Cat()  
    45.      {  
    46.     printf(" Cat construct! \n");  
    47.      }  
    48.      virtual void shout() // 必须要被实现,即使函数体是空的  
    49.      {  
    50.          printf(" Cat: miao! miao! miao! \n");  
    51.      }  
    52.       
    53.      virtual void impl()  
    54.      {  
    55.          printf(" Cat: implement of Cat!  \n");  
    56.      }  
    57.      virtual ~Cat() {printf(" Cat destory! \n");};   // 虚析构函数  
    58. };  
    59.   
    60.   
    61. /* 
    62. Animal f()  // error, 抽象类不能作为返回类型 
    63. { 
    64.        
    65. } 
    66.  
    67. void display( Animal a) //error, 抽象类不能作为参数类型 
    68. { 
    69.      
    70. } 
    71. */  
    72.   
    73.   
    74. //ok,可以声明抽象类的引用  
    75. Animal &display(Animal &a)  
    76. {  
    77.        Dog d;  
    78.        Animal &p = d;  
    79.        return p;  
    80.         
    81. }  
    82.   
    83. void test_func()  
    84. {  
    85.      //Animal a;  // error: 抽象类不能建立对象  
    86.       
    87.     Dog dog;   //ok,可以声明抽象类的指针  
    88.     Cat cat;   //ok,可以声明抽象类的指针  
    89.      
    90.     printf("\n");  
    91.   
    92.     Animal *animal = &dog;  
    93.     animal->shout();  
    94.     animal->impl();  
    95.      
    96.     printf("\n");  
    97.      
    98.     animal = &cat;  
    99.     animal->shout();  
    100.     animal->impl();  
    101.      
    102.     printf("\n");  
    103. }  
    104.   
    105. int main()  
    106. {  
    107.     test_func();  
    108.   
    109.     while(1);    
    110. }  
    111.   
    112.   
    113. //result:  
    114. /* 
    115. Animal construct! 
    116. Dog construct! 
    117. Animal construct! 
    118. Cat construct! 
    119.  
    120. Dog: wang! wang! wang! 
    121. Dog: implement of Dog! 
    122.  
    123. Cat: miao! miao! miao! 
    124. Cat: implement of Cat! 
    125.  
    126. Cat destory! 
    127. Animal destory! 
    128. Dog destory! 
    129. Animal destory! 
    130. */  
    131. (YC:代码已调试无误)  


    四. 巧用纯虚析构函数实现接口类
    c++不像java一样有纯接口类的语法,但我们可以通过一些手段实现相同的功能。

    (1)能不能用“protected”实现接口类?

    看如下代码:

    1. #include <stdio.h>  
    2.   
    3.   
    4. class A  
    5. {  
    6. protected:  
    7.     virtual ~A()  
    8.     {  
    9.         printf(" A: 析构函数  \n");  
    10.     }  
    11. };  
    12. class B : public A  
    13. {  
    14. public:  
    15.     virtual ~B()  
    16.     {  
    17.         printf(" B: 析构函数  \n");  
    18.     }  
    19. };  
    20. int _tmain(int argc, _TCHAR* argv[])  
    21. {  
    22.     //A* p1 = new A;              //error:[1]有问题  
    23.     //delete p1;  
    24.   
    25.   
    26.     B* p2 = new B;           //ok:[2]没问题,输出结果为:  
    27.     delete p2;               /* B: 析构函数 
    28.                                         A: 析构函数*/(注意此处还是会调用A的析构函数的,不过编译没问题)  
    29.                    
    30.     //A* p3 = new B;  
    31.     //delete p3;                 //error:[3] 有问题  
    32.   
    33.   
    34.     return 0;  
    35. }  

    通过在类中,将类的构造函数或者析构函数申明成protected ,可以有效防止类被实例话,要说实用的话,构造函数是protected更有用,肯定能保证类不会被实例化,而如果析构函数是protected的话,构造函数不是protected的话,还可能存在编译通过的漏洞,如下:

    Case1:

    1. class A  
    2. {  
    3. protected:  
    4.     A()  
    5.     {  
    6.         printf(" A: A()  \n");  
    7.     }  
    8. };  
    9.   
    10. int _tmain(int argc, _TCHAR* argv[])  
    11. {  
    12.     A* p1 = new A;                //编译不通过,无法访问protected构造函数  
    13.     delete p1;  
    14.   
    15.     return 0;  
    16. }  

    Case2:

    1. class A  
    2. {  
    3. protected:  
    4.     ~A()  
    5.     {  
    6.         printf(" A: ~A()  \n");  
    7.     }  
    8. };  
    9.   
    10. int _tmain(int argc, _TCHAR* argv[])  
    11. {  
    12.     A* p1 = new A;                //编译通过,此时因为仅仅是用到了A的构造函数,还不需要它的析构函数  
    13.     return 0;  
    14. }  
    15.   
    16. (附:如果将main中改为:  
    17. int _tmain(int argc, _TCHAR* argv[])  
    18. {  
    19.     A a;  
    20.     return 0;  
    21. }  
    22. 则编译出错,提示无法访问protected成员A::~A().两种情况出现差异的原因是什么?  
    23.   
    24. )  

    Case3:

    1. class A  
    2. {  
    3. protected:  
    4.     ~A()  
    5.     {  
    6.         printf(" A: ~A()  \n");  
    7.     }  
    8. };  
    9. int _tmain(int argc, _TCHAR* argv[])  
    10. {  
    11.     A* p1 = new A;                  
    12.     delete p1;                //编译失败,因为编译器发现A的析构函数是protected  
    13.     return 0;  
    14. }  


    所以,一种可行的办法貌似是这样的:

    1. class A  
    2. {  
    3. protected:  
    4.     virtual ~A()  
    5.     {  
    6.         printf(" A: ~A()  \n");  
    7.     }  
    8. };  
    9.   
    10. class B : public A  
    11. {  
    12. };  
    13.   
    14. int _tmain(int argc, _TCHAR* argv[])  
    15. {  
    16.     B* p =new B;       //ok:这种情况下确实是可行的(YC:仔细看会发现这种情况同“(1)看如下代码”下面的代码中ok的情况相同)  
    17.     delete  p;  
    18.     return 0;  
    19. }  

    由于B public继承自A,所以其可以完全访问A的构造或析构函数,但是:

    1. int _tmain(int argc, _TCHAR* argv[])  
    2. {  
    3.     A* p =new B;  
    4.     delete  p;                //error:由于p变成指向A的指针,字面上编译器需要知道A的析构函数,然后A的析构函数又是protected  
    5.     return 0;  
    6. }  

    即便像这样B显示重载了A的析构函数:

    1. class A  
    2. {  
    3. protected:  
    4.     virtual ~A()  
    5.     {  
    6.         printf(" A: ~A()  \n");  
    7.     }  
    8. };  
    9. class B : public A  
    10. {  
    11. public:  
    12.     virtual ~B()  
    13.     {  
    14.         printf(" B: ~B()  \n");  
    15.     }  
    16. };  
    17. int _tmain(int argc, _TCHAR* argv[])  
    18. {  
    19.     A* p =new B;  
    20.     delete  p;        //error:也还是不行,因为重载是运行时的事情,在编译时编译器就认定了A的析构函数,结果无法访问  
    21.     return 0  
    22. }  

    小结:

    貌似用protected这样的方法并不是很恰当,虽然在遵守一定规则的情况下确实有他的实用价值,但并不是很通用

    (2)应该怎样实现接口类?

    其实上面protected的思路是对的,无非是让父类无法实例化,那么为了让父类无法实例化,其实还有一个方法,使用纯虚函数

    1. class A  
    2. {  
    3. public:            //这里就不用protected了  
    4.     virtual ~A() = 0;  
    5. };  
    6. class B : public A  
    7. {  
    8. };  
    9. int _tmain(int argc, _TCHAR* argv[])  
    10. {  
    11.     B* p =new B;  
    12.     delete  p;      //编译ok,链接error  
    13.     return 0;  
    14. }  

    这样写貌似不错,以往大家都把类中的一般成员函数写成纯虚的,这次将析构函数写成纯虚的,更加增加通用性,编译也通过了,但就是在链接的时候出问题,报错说找不到A的析构函数的实现,很显然嘛,因为A的析构是纯虚的嘛。

    那么如何修改上述代码可以达到既可以去除上述error,又可以让基类不能被实例化呢?如下所示:

    1. class A  
    2. {  
    3. public:                 //这里就不用protected了  
    4.     virtual ~A() = 0                //它虽然是个纯虚函数,但是也可以被实现  
    5.     {                               //这个语法很好很强大(完全是为了实现其接口类而弄的语法吧)  
    6.         printf(" A: ~A()  \n");  
    7.     }  
    8. };  
    9. class B : public A  
    10. {  
    11. };  
    12. int _tmain(int argc, _TCHAR* argv[])  
    13. {  
    14.     B* p =new B;  
    15.     delete  p;  
    16.     A* p2 =new B;  
    17.     delete  p2;            //不用担心编译器报错了,因为此时A的析构函数是public  
    18.     return 0;  
    19. }  
    20. //result:  
    21. /* 
    22.  A: ~A() 
    23.  A: ~A() 
    24. */   

    如此终于大功告成了,注意,不能将构造函数替代上面的析构函数的用法,因为构造函数是不允许作为虚函数的

    补充:以上那个语法就真的只是为了这种情况而存在的,因为一般我们在虚类中申明的接口:

    virtual foo()= 0;

    virtual foo()= 0 {}

    这两种写法是完全没有区别的纯虚函数的默认实现,仅仅在它是析构函数中才有意义!!!

    所以可以说,老外是完全为了这一个目的而发明了这种语法...

    最终的接口类

    1. classInterface  
    2. {  
    3. public:         
    4.     virtual ~Interface() = 0 {}  
    5. };  

    应该挺完美的了吧
    展开全文
  • 纯虚函数和虚函数都是使用virtual关键字,只是纯虚函数在函数原型后面加上“=0”。 含有纯虚函数的类是抽象类,不能实例化/生成对象,只能派生,它派生的类的纯虚函数如果没有重写,那么,它的派生类也是抽象类。...
    1. 纯虚函数和虚函数都是使用virtual关键字,只是纯虚函数在函数原型后面加上“=0”。
    2. 含有纯虚函数的类是抽象类,不能实例化/生成对象,只能派生,它派生的类的纯虚函数如果没有重写,那么,它的派生类也是抽象类。定义纯虚函数就是为了让基类不能实例化,因为实例化这样的抽象数据结构是没有意义的(比如:熊猫、老虎、长颈鹿的基类:动物,实例化动物没有意义)
    3. 纯虚函数可以有函数体,但必须定义在类的外部。
    4. 虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。当我们使用基类的引用(或指针)调用一个虚函数时将发生“动态绑定”(dynamic binding),运行时才知道指针指向的是哪个对象类型。
      1. 强行调用基类中定义的函数版本而不管基类的动态类型是什么
        int a = baseP->Base::fun();

         

      2. 基类中的虚函数需要实现,不然多态无从谈起
      3. 普通函数(非成员函数)、静态成员函数、内联成员函数、构造函数、友元函数
    #include <iostream>
    
    using namespace std;
    
    class A{
    public:
      virtual void f(const string& str)=0;
      virtual void e() {
        cout << "Base e() : " << endl;
      }
    };
    // 缺省实现,纯虚函数可以有函数体,但必须类的外部定义,如果子类不想实现,可以调用基类的
    void A::f(const string& str) {
       cout << "A f()" << str << endl;
    }
    
    class B : public A{
    public:
    // 本质上还是重写了,只不过直接调用了基类的函数实现
      virtual void f(const string& str){
        cout << "Call A::f " << endl;
        A::f(str);
      } 
      void e(){
        cout << "B e()" << endl;
      }
    };
    
    int main()
    {
      B b;
      b.f("hello world");
      b.e();
      A *a = new B();
      // 都是多态
      a->f("hello");
      a->e();
      return 0;
    }

    参考:

    https://www.cnblogs.com/this-543273659/archive/2011/08/20/2147286.html

    https://blog.csdn.net/lisemi/article/details/103928596

    展开全文
  • 纯虚函数和虚函数重写调用 class parent { public: parent(int a, int b) { this->a = a; this->b = b; cout << "我是爸爸构造函数" << endl; } void printfP() { dotest(); }...

    纯虚函数和虚函数重写调用

     

    class parent
    {
    public:
    	parent(int a, int b)
    	{
    		this->a = a;
    		this->b = b;
    		cout << "我是爸爸构造函数" << endl; 
    	}
    	void printfP()
    	{
    		dotest();
    	}
    	virtual void dotest()
    	{
    		cout << "parent:dotest()" << endl;
    	}
    	~parent()
    	{
    		cout << "我是爸爸析构函数" << endl;
    	}
    private:
    	int a;
    	int b;
    };
    class child :public parent
    {
    public:
    	child(int a, int b, int c) :parent(a, b)
    	{
    		this->c = c;
    		cout << "我是儿子构造函数" << endl;
    	}
    	~child()
    	{
    		cout << "我是儿子析构函数" << endl;
    	}
    	virtual void dotest()
    	{
    		cout << "child:dotest()" << endl;
    	}
    private:
    	int c;
    };
    //在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化
    //在系类对象析构时,需要调用父类析构函数对其继承得来的成员进行处理
    //先调用父类构造函数 再调用子类构造函数
    void objplay()
    {
    	child c(1, 2, 3);
    	c.printfP();
    }
    
    void main()
    {
    	objplay();
    	getchar();
    }

     

    基类的printfP函数此时调用的dotext 是子类重写的方法,其实每个函数里面隐藏一个this指针的,由于创建了子类child的实例,this就是子类的指针1,当谁调用了改该方法,传递的this就是该对象的,顾名思义 child c(1, 2, 3);  c.printfP(); dotext 时调用的 是子类的方法

    展开全文
  • 1、纯虚函数声明如下: virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或...
  • C++纯虚函数和虚函数

    2019-05-08 16:53:10
    在Java、C#中有关键词abstract指明抽象函数、抽象类,但是在C++中没有这个关键词,很显然,在C++也会需要只需要在基类声明某函数的情况,而不需要写具体的实现,那C++中是如何实现这一功能的,答案是纯虚函数。...
  • 1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。 2.虚函数可以被直接使用,也可以被子类...
  • 纯虚函数虚函数的作用是实现多态性(Polymorphism),多态性是将接口与实现进行分离,采用共同的方法,但因个体差异而采用不同的策略。纯虚函数则是一种特殊的虚函数纯虚函数在基类中,定义...
  • 什么是虚函数? 那些被virtual关键字修饰的成员函数,就是虚函数虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因...
  • 1、纯虚函数的声明除过像虚函数加关键字virtual而外,还必须加 = 0; 2、声明为虚函数,为了能让这个函数在它的派生类里面被覆盖(或隐藏),这样编译器就可以通过后期绑定达到多态性。 3、声明为纯虚函数,有一种...
  • 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数 定义一个函数为纯虚函数,才代表函数没有... 普通的类(没有虚函数纯虚函数
  • C++中的虚函数和纯虚函数用法 象这样定义的就是纯虚函数 virtual void f(void) = 0; 象这样的就是虚函数 virtual void f(void);  1.虚函数和纯虚函数可以定义在同一个类(c...
  • C++的纯虚函数导致声明它的类成为抽象类,即不可以实例化,派生于这个基类的类必须重新声明所有的纯虚函数。通常纯虚函数不在基类中定义,所以派生类实际上是继承了这些纯虚函数形式的接口,它告诉派生类:你必须...
  • 1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。   2. 虚函数可以被直接使用,也可以被子类...
  • 原因是这样的:子类继承父类时,必须重写父类的纯虚函数,函数名、返回类型、参数个数类型都不能改。若父类中的虚函数自己有定义,子类也可以不重写。 测试如下: 头文件test.h#pragma once #include "iostream...
  • 纯虚函数能被子类继承,且子类如果依旧不定义的话,则子类也是抽象类虚函数被声明了,必须被定义,不用被定义的只有纯虚函数
  • 面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念。因为它充分体现了面向对象思想中的继承多态性这两大特性,在C++语言里应用极广。比如在微软的MFC类库中,你会发现很多函数都有virtual...
  • C++的类要实现多态,不像java,直接就有,而是需要给...虚函数如上面所说的,加上virtual即可,因为不是纯虚函数,所以也同样需要提供函数的定义纯虚函数除了同样必须要有virtual关键字外,函数的定义不是必须的,...
  • 虚函数纯虚函数区别虚函数为了重载多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!...
  • //纯虚函数 没有函数体的函数 class A{  private:  int a;  public:  virtual void Print() = 0;//纯虚函数  void fun(){  cout  } }; //包括纯虚函数的类就是抽象类 //只能作为基类来派生新类...

空空如也

空空如也

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

纯虚函数和虚函数