多重继承 多态

基类和派生类之间地址的相互转换

class DeckChair:public Bed,public Chair

{

    int num;

};

int mian()

{Bed*

    DeckChair dc(10);

Bed* bp=static_cast<Bed*>(&dc);

Chair* cp=static_cast<Chair*>(&dc);  //派生类转成基类  ok

DeckChair* dp=&dc;

dp=static_cast<DeckChair*>(bp);    

dp=static_cast<DeckChair*>(cp);   //基类转成派生类   no

dc.Bed::fun();

dc.Chair::fun();  //如果遇到基类中的成员函数名相同

cp->fun();

dp->fun();

}

//如果是钻石继承,为了避免二义性

int main()

{

   EStudent es;

Person* p=(Employee*)&es;   //这样赋值避免二义性

p=(Student*)&es;

}

数据冗余和二义性的解决办法:

对基类进行虚继承

虚基类:

     两个身份证号显然是不合理的。可以把class Person这个共同基类设置为虚基类,这样从不同路径继承来的同名数据成员在内存中就只有一个拷贝,同名函数也只有一种映射。

虚基类(virtual base class)定义方式如下:

class 派生类名:virtual 访问限定符 基类类名{...};

class 派生类名:访问限定符 virtual 基类类名{...};

原理:构造虚基时,将内存布局改变,在构造虚基时将另外开辟一个空间,将在继承虚基的派生类中存放虚基的指针或者存储虚基的偏移量。这样就可以保证同一种虚基只有一个。

多态和虚函数

多态:

多态性是面向对象程序设计的关键技术之一。

多态性是考虑在不同层次的类中,以及在同一类中,同名成员函数之间的关系问题。

函数的重载,运算符的重载,属于编译时的多态性。

以类的虚成员函数为基础的运行时的多态性,是面向对象程序设计的标志性特征。体现了类推和比喻的思想方法。

c++有两种多态:1.编译时的多态:通过函数的重载和运算符的重载来实现的

2.运行时的多态:运行时的多态性是指在程序执行前,无法根据函数名和参数来确定该调用哪一个函数,必须在程序执行过程中,根据执行的具体情况来动态地确定。它通过类继承关系public和虚函数来实现的。目的也是建立一种通用的程序。通用性是程序追求的主要目标之一。

有三个条件:1.public继承 2.必须有虚函数3.必须调用指针或者引用

运行时的多态设计思想:

  对于相关的类型,确定它们之间的一些共同特征,(属性和方法),将共同特征被转移到基类中,然后在基类中,把这些共同的函数或者方法声明为公有的虚函数接口。然后使用派生类继承基类,并且在派生类中重写这些虚函数,以完成具体的功能。

   客户端代码(操作函数)通过基类的引用或者指针来指向这些派生类型对象,对虚函数的调用会自动绑定到派生类对象上重写的虚函数。

class Animal

{

 

 private:     //cat和dog的共同属性和方法

  string name;

  string owner;

publci:

 virtual void eat(){cout<<"eat...."<<endl;}

virtual  void walk() {cout<<"walk..."<<endl;}

virtual  void talk() {cout<<"talk..."<<endl;}

 

};

class Gog:public Animal

{

public:

    Dog(const string& na,const string& ro):Animal(na,ro) {}

void eat(){cout<<"Dog Eat:bone"<<endl;}

void walk() {cout<<"Dog walk:run..."<<endl;}

void talk() {cout<<"Dog talk:wangwang "<<endl;}

};

class Cat:public Animal

{

public:

    Dog(const string& na,const string& ro):Aniaml(na,ro){}

void eat(){cout<<"Cat Eat:fish"<<endl;}

void walk() {cout<<"Cat walk:silent"<<endl;}

void talk() {cout<<"Cat talk: miao miao"<<endl;}

};

void fun(Animal* p)

{

   p->eat();

  p->talk();

 p->walk();

}

int main()

{

   Cat cat("bsm","yhping");

   Dog gog("erh","gg");

fun(&cat);

fun(&dog);

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值