美文网首页
10 多态 抽象

10 多态 抽象

作者: LuckTime | 来源:发表于2016-06-18 09:56 被阅读8次

    /*
    多态本质:c++ 允许将派生类对象的地址赋予基类的指针
    所有派生类的本质都是is a 的基类
    基类的指针调用任何方法,c++都能找到相应派生类的方法

    多态优势:统一管理。。统一的操作接口
    p->show();
    使用多态要点
    1.存在继承关系。
    2.(存在虚函数,才能使用多态)
    3.访问的必须是对象本身(用指针 或引用或 自己),不能是另一个对象
    4.构造函数,通常不使用虚函数,因为不经常调用。
    如果任何一个成员函数是虚函数,那么析构函数应该是虚函数
    如果一个类肯定被其他派生类当做基类,尽量使用虚函数
    */

    include <iostream>

    include <string>

    using namespace std;

    class Animal
    {
    string name; //string 内部封装的是一个指针
    public :
    virtual void eat() //当使用虚函数时,会分配一部分内存放置虚函数。增加4个字节(但在一个类中,不管使用多少个virtual,都只占,原先分配的字节数)
    {
    cout <<"Animal eat something!" <<endl;
    }
    virtual void sleep()
    {
    cout <<"Animal need sleep"<<endl;
    }

    virtual void shout()
    {
    cout << "Animal can shout" <<endl;
    }
    };

    class Cat :public Animal
    {
    string name;
    public:
    void eat() //当使用虚函数时,会分配一部分内存放置虚函数。增加4个字节(但在一个类中,不管使用多少个virtual,都只占,原先分配的字节数)
    {
    cout <<"Cat eat mouse!" <<endl;//调用虚函数时,只需要将基类virtual函数就行咯
    }
    virtual void sleep()
    {
    cout <<"Cat sleep on table"<<endl;
    }
    virtual void shout()
    {
    cout << "Cat shout is miaomiao" <<endl;
    }
    };

    class Jiafei :public Cat
    {
    public:
    virtual void eat() //当使用虚函数时,会分配一部分内存放置虚函数。增加4个字节(但在一个类中,不管使用多少个virtual,都只占,原先分配的字节数)
    {
    cout <<"Jiafei eat noodle!" <<endl;//调用虚函数时,只需要将基类virtual函数就行咯
    }
    virtual void sleep()
    {
    cout <<"Jiafei sleep on bed"<<endl;
    }
    virtual void shout()
    {
    cout << "Jiafei shout how a you" <<endl;
    }
    };

    class Player
    {
    string name;
    public :

    Player(string n) :name(n){cout << name <<":"<< endl;}
    void play(Animal* p)
    {
    p->eat(); //指针 基类的指针,指向派生类的地址
    p->shout();
    p->sleep();
    }

    void play(Animal& p)
    {
    p.eat();
    p.shout();
    p.sleep();
    }
    };////////////////领养者新类
    int main()
    {
    /*cout << sizeof(Animal) <<endl;
    Animal a;
    a.eat();
    a.shout();
    a.sleep();

    Cat c ; //===============自己
    c.eat();
    c.shout();
    c.sleep();

    Cat& d = c ; //==============引用
    d.eat();
    d.shout();
    d.sleep();

    Cat* p; //================指针调用自身
    p = &c;
    p->eat();

    Animal* q = NULL;//===========基类的指针,指向派生类的地址,输出的是派生类
    q = &c;
    q->eat();

    Animal& w = c;//===========基类的引用(别名),指向派生类的地址,输出的是派生类
    w.eat();

    Jiafei f;
    f.eat(); //=========加菲吃什么

    Cat* y;
    y = &f; //==========用基类的指针,指向派生类地址
    y->sleep();

    //Jiafei* i;
    //i = &c; //error !,不能派生类指针,指向基类的地址
    //i->eat();
    */

    Cat c;
    Jiafei j;
    Player p("liu");
    p.play(j); // 引用,传入变量(play(& p))
    p.play(&c); //指针,传入指针(play(* p))
    }
    //================================
    //================================
    //================================
    virtual 使用多态方法(关键字)虚函数

    include <iostream>

    using namespace std;

    class Frac
    {
    int n;
    int d;
    public :
    Frac() : n(0),d(1){}
    Frac(int an,int ad) :n(an),d(ad){
    reduct();
    }

    void reduct()
    {
    if( d < 0 ) { n = -n ; d = - d;}
    if( d == 0 ) { cout << "d ==0!!error" <<endl; }
    int adsn = n < 0 ? -n : n;
    for(int i = d; i > 1; i--)
    {
    if(d % i == 0 && adsn % i == 0)
    {
    d /= i;
    n /= i; break;
    }
    //因为从大向小找最大公约数,只要找到一个,就跳出循环了,记住。break的位置
    }
    }

    virtual void show() //============使用多态
    {
    cout << n <<"/" << d << endl;
    }
    virtual double value() //=======使用多态(通过指针,访问某个函数。会根据对象的真实类型,访问相应的类中函数)
    {
    return (double) n/d ;
    }
    };

    //===============分数Frac的子类
    class Dai : public Frac
    {
    int integer;
    public:
    Dai():integer(0){}

    Dai(int a,int an, int ad):integer(a),Frac(an,ad){

    }

    void show()
    {
    cout << integer <<" ";
    Frac ::show();
    }
    double value()
    {
    return integer+Frac::value() ;
    }
    };

    int main()
    {
    /*
    Frac f1(12,16);
    Frac f3;
    Frac* p = NULL;
    p = &f3;
    p->show();
    cout<<p->value() << endl;
    f1.show();
    f1.value();
    Dai f2(3,12,16);
    f2.show();
    f2.value();

    /
    ////=====================理解加深(水杯,水桶理论)
    Frac f1(12,16);
    Dai f2(3,12,16);
    Frac
    p =NULL ; //指针
    p = &f1;
    p->show(); //调用 frac分数
    p = &f2; //调用dai分数
    p->show();

    //========================
    Frac& f = f2; //利用了引用别名。
    f.show(); //调用带分数 //3 3/4
    Frac f3 = f2;
    f3.show(); //调用frac分数 3/4
    //f3 明确的说明是分数类,只是调用带分数。而f2是指针类型,调用带分数
    }

    /*
    多态本质:c++ 允许将派生类对象的地址赋予基类的指针
    所有派生类的本质都是is a 的基类
    基类的指针调用任何方法,c++都能找到相应派生类的方法

    p->show();

    */
    //=========================================
    //=========================================
    //=========================================

    include <iostream>

    include <string>

    using namespace std;

    class Art
    {
    char* name;
    char* title;
    int time;
    public : //构造函数字符串的传入
    Art(char* n, char* t,int ti):time(ti){
    cout << "一般构造函数被调用 !\n";
    name = new char[strlen(n) + 1];
    title = new char[strlen(t) + 1];
    //在堆中开辟一个内存块存放pN所指的字符串
    if(name != NULL && title !=NULL )
    {
    //如果m_pName不是空指针,则把形参指针pN所指的字符串复制给它
    strcpy(name ,n);
    strcpy(title,t);
    }

    }

    Art(){}
    ~Art(){}

    void show(){
    cout << name << title << time<<endl;
    }
    };

    int main(int argc,char *argv[])
    {
    Art a("lx","Gb",1991);
    a.show();

    }
    //、======================

        // 系统创建的默认复制构造函数,只做位模式拷贝
        Person(Person & p)    
        { 
                  //使两个字符串指针指向同一地址位置         
                 m_pName = p.m_pName;         
        }
    
        ~Person( )
        {
                delete m_pName;
        }
    

    2.。。。。。。。。。。。。。。。。。。。。。
    Person(Person & chs);
    {
    // 用运算符new为新对象的指针数据成员分配空间
    m_pName=new char[strlen(p.m_pName)+ 1];

         if(m_pName)         
         {
                 // 复制内容
                strcpy(m_pName ,chs.m_pName);
         }
      
        // 则新创建的对象的m_pName与原对象chs的m_pName不再指向同一地址了
    

    }

    相关文章

      网友评论

          本文标题:10 多态 抽象

          本文链接:https://www.haomeiwen.com/subject/gonvdttx.html