C++学习笔记11--纯虚函数和抽象类

  纯虚函数:没必要或者不应该有函数体的虚函数,用"=0;"来取代函数体。有纯虚函数的类称为抽象类(缺少函数体),不允许直接用抽象类来创建对象。抽象类总数用来作为父类,由子类来实现(覆盖)那些纯虚函数,从而可以创建子类类型的对象。子类对象可以当成父类对象的引用,或者可以用父类指针指向子类对象。

  ×××××使用多态时必须通过父亲指针或者引用来访问子对象,而不能重建一个父类对象×××× 

  抽象类:为了抽象和设计的目的而建立的,处于继承层次结构的上层。

    具体类是能够建立对象的类。

    抽象类的规定

      (1)抽象类只能用作其他类的基类,不能建立抽象类对象。

      (2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。

      (3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。

#include<iostream>
using namespace std;
#include<string>

class Graph{//抽象类
    int x;
    int y;
public:
    Graph(int x,int y):x(x),y(y){}
    virtual double area()=0; //纯虚函数
    virtual string Type()=0; //纯虚函数
    void show(){
    cout <<Type()<< "位置("<<x<<","<<y<<"),面积"<<area()<<endl;
    } 
};

class Rect:public Graph{
    int w;
    int h;
public:
    Rect(int x,int y, int w,int h):Graph(x,y),w(w),h(h){}
    double area(){return w*h;}
    string Type(){return "矩形";}
};

class Circle:public Graph{
    int r;
public:
    Circle(int x,int y,int r):Graph(x,y),r(r){}
    double area(){return 3.14*r*r;}
    string Type(){return "圆形";}
};

class computer{
public:
    static void useGraph(Graph& g){g.show();}
};

int main()
{
    Circle c(8,8,10);
    Rect r(0,0,20,5);
    computer::useGraph (c);
    computer::useGraph (r);
    system("pause");
}

 

       练习:写一个Coder类,有两个纯虚函数code和decode 写一个rm类和一个divx类,分别继承coder类并且实现那两个纯虚函数。写一个File类,有一个setcoder函数、zip函数和unzip函数。在main函数中使用这些类的对象

#include <iostream>
using namespace std;
#include <string>

class Coder{
public:
    virtual void code(char* input,char* output) =0;
    virtual void decode(char* input,char* output) =0;
    Coder(){}
};

class rm:public Coder{
public:
    void code(char* input,char* output){
        cout<<"RM编码!"<<endl;
    }
    void decode(char* input,char* output){
        cout<<"RM解码!"<<endl;
    }
};

class divx:public Coder{
public:
    void code(char* input,char* output){
        cout<<"Divx编码!"<<endl;
    }
    void decode(char* input,char* output){
        cout<<"Divx解码!"<<endl;
    }
};
class File{
    Coder* p;
public:
    void setCoder(Coder& c){p=&c;}
    void zip(){
        char* source=NULL,*result=NULL;
        p->code(source,result);
        cout<<"保存到文件中"<<endl;
    }
    void unzip(){
        char* source = NULL,*result=NULL;
        p->code(source,result);
        cout<<"播放文件"<<endl;
    }
};

int main()
{
    File f;
    rm r;
    divx d;
    f.zip();
    f.setCoder(r);
    f.unzip();

    f.zip();
    f.setCoder (d);
    f.unzip ();

    system("pause");
    return 0;
}

    多态也称为动态绑定、晚绑定、运行时绑定。统一接口,便于替换和维护。

    通过父类指针动态释放子类对象时,默认调用父类析构。如果希望使用多态调用对象所属的子类的析构函数,应该在父类中把析构也声明为虚函数 

    

#include<iostream>
using namespace std;
class A{
public:
    A(){cout<<"A()"<<endl;}
    virtual ~A(){cout<<"~A()"<<endl;} //虚析构函数也声明为虚函数
    virtual void dosomething(){}
};

class B: public A{
public:
    B(){cout<<"B()"<<endl;}啊
    virtual ~B(){cout<<"~B()"<<endl;}//虚析构函数也声明为虚函数
};

int main()
{
    A* x[2];
    x[0] = new B();
    x[1]= new A();
    //dosomething...
    delete x[0];
    delete x[1];
    system("pause");
}

 

posted @ 2016-05-18 19:31  Visions  阅读(161)  评论(0编辑  收藏  举报