c++ 虚函数和纯虚函数

Posted ike_li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 虚函数和纯虚函数相关的知识,希望对你有一定的参考价值。

 

  在你设计一个基类的时候,如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的。从设计的角度讲,出现在基类中的虚函数是接口,出现在派生类中的虚函数是接口的具体实现。通过这样的方法,就可以将对象的行为抽象化。

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

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

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

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

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

   纯虚函数
    1, 当在基类中不能为虚函数给出一个有意义的实现时,可以将其声明为纯虚函数,其实现留待派生类完成。 
    2, 纯虚函数的作用是为派生类提供一个一致的接口。
    3, 纯虚函数不能实化化,但可以声明指针。

    纯虚函数在基类只声明不用定义,继承类必须实现。

虚函数和纯虚函数对比:

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

2. 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class) 只有声明而没有定义。

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

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

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

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

 

 

 

#pragma once
class Shape
{
   public:
    Shape();
    virtual ~Shape();

    void Draw1();
    virtual void Draw2();
    virtual void Draw3()=0;
};
#include "Shape.h"
#include <iostream>

using namespace std;
Shape::Shape()
{
    cout << "shape 构造函数" << endl;
}


Shape::~Shape()
{
    cout << "shape 析构函数" << endl;
}


void Shape::Draw1()
{
    cout << "shape Draw1 画个图形" << endl;
}
void Shape::Draw2()
{
    cout << "shape Draw2 画个图形" << endl;
}
#pragma once
#include "Shape.h"
class Rectangle:public Shape
{
    public:
        Rectangle();
       ~Rectangle();

       void Draw1();
       void Draw2();
       void Draw3();
};
#include "Rectangle.h"
#include <iostream>

using namespace std;
Rectangle::Rectangle()
{
    cout << "Rectangle 构造函数" << endl;
}


Rectangle::~Rectangle()
{
    cout << "Rectangle 析构函数" << endl;
}

void Rectangle::Draw1()
{
    cout << "Rectangle Draw1 画个矩形" << endl;
}
void Rectangle::Draw2()
{
    cout << "Rectangle Draw2 画个矩形" << endl;
}

void Rectangle::Draw3()
{
    cout << "Rectangle Draw3 画个矩形" << endl;
}
#pragma once
#include "Shape.h"
class Circle:public Shape
{
   public:
     Circle();
     ~Circle();
     void Draw1();
     void Draw2();
     void Draw3();
};
#include "Circle.h"
#include <iostream>

using namespace std;
Circle::Circle()
{
    cout << "Circle 构造函数" << endl;
}


Circle::~Circle()
{
    cout << "Circle 析构函数" << endl;
}
void Circle::Draw1()
{
    cout << "Circle Draw1 画个圆形" << endl;
}
void Circle::Draw2()
{
    cout << "Circle Draw2 画个圆形" << endl;
}

void Circle::Draw3()
{
    cout << "Circle Draw3 画个圆形" << endl;
}

 

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<memory>
#include "Shape.h"
#include "Rectangle.h"
#include "Circle.h"


using namespace std;
void Run()
{

    //Shape *_c;
    //_c = new Rectangle();
    //_c->Draw1();
    //_c->Draw2();

    //_c = new Circle();
    //_c->Draw1();
    //_c->Draw2();

    //delete _c;

    shared_ptr<Shape> _s(new Rectangle());
    _s->Draw1();
    _s->Draw2();
    _s->Draw3();
    _s.reset(new Circle());
    _s->Draw1();
    _s->Draw2();
    _s->Draw3();




}

int main()
{

    Run();
    
    
    system("pause");
    return 0;
}

运行结果:

shape 构造函数
Rectangle 构造函数
shape Draw1 画个图形
Rectangle Draw2 画个矩形
Rectangle Draw3 画个矩形
shape 构造函数
Circle 构造函数
Rectangle 析构函数
shape 析构函数
shape Draw1 画个图形
Circle Draw2 画个圆形
Circle Draw3 画个圆形
Circle 析构函数
shape 析构函数
请按任意键继续. . .

以上是关于c++ 虚函数和纯虚函数的主要内容,如果未能解决你的问题,请参考以下文章

C++ 虚函数和纯虚函数的区别

c++ 虚函数和纯虚函数

C++:抽象基类和纯虚函数的理解

C++中的继承和纯虚函数

一个例子彻底搞懂C++的虚函数和纯虚函数

一口气搞懂《虚函数和纯虚函数》