C++笔记记录Ⅲ 继承与多态

>ㅂ< 开学啦上课啦 更一点啦

就从刚上的记起。。。

-----------------------------------------------------------------

面向对象语言四大特点:抽象  封装  继承  多态

类和类之间基本关系:组合代理继承

类:封装和隐藏。                              

 模板:对类型进行参数化。

运算符重载:对象的运算和基本类型的运算一致。  

继承:代码的复用。

-----------------------------------------------------------------

class Base//基类sizeof(Base)=12

{

public:

int a;

protected:

char b;

private:

float c;

};

class Derive:public Base//派生类sizeof(Derive)=24

{

public:

int d;

protected:

char e;

private:

float f;

 

};

★派生类继承除构造和析构外基类的所有成员和他们的作用域。

 Protected和private的主要区别在继承,protected用于继承结构中。

 Private只有自己和友元可见,派生类可继承但不可见,可通过基类提供的函数间接访问。


这里补充说一点:VS/VC下,*.c不允许定义空struct。C++中,sizeof(空class)=1,sizeof(空struct)=1

gcc下,C中sizeof(空struct)=0,C++中,sizeof(空class)=1,sizeof(空struct)=1

---------------------------------------------------------------------------------------------------------------------------------------------

派生类无法构造基类继承来的部分,只能构造自己的那部分

★最先构造成员对象(如果有) 然后构造基类 再构造派生类

对于基类和派生类名字相同的成员(方法):

重载    函数名同,参数列表不同,作用域同

隐藏    继承结构中,基类、派生类中有相同的名字

覆盖    继承结构中,基类有虚函数,且派生类有相同名,相同参数,返回值,则基类该函数被覆盖。


然后又是一个栗子:

class Base

{

public:

Base(int a):ma(a){cout<<"Base()"<<endl;}

~Base(){cout<<"~Base()"<<endl;}

void show(){cout<<"lalala"<<endl;}//隐藏,可用作用域访问

void show(int m){cout<<ma<<endl;}//隐藏,可用作用域访问

void fun(){cout<<"???"<<endl;}//可被派生类对象调用

protected:

int ma;

};


class Derive:publicBase

{

public: 

Derive(int a):mb(a),Base(a){}//基类在派生类成员初始化列表构造

~Derive(){}

void show(){cout<<"xixixi"<<endl;}

private:

int mb;

};


int main()

{

Derive d(2);

d.Base::show();

d.Base::show(2);

d.fun();

Base *= &d;

p->show();//编译阶段就可确定show()来自哪个类,静态绑定(普通函数)

//call Base::show()

cout<<typeid(p).name()<<endl;//Base*

cout<<typeid(*p).name()<<endl;//Base

cout<<sizeof(Derive)<<endl;//8

}

class Base

{

public:

Base(int a):ma(a){cout<<"Base()"<<endl;}

~Base(){cout<<"~Base()"<<endl;}

virtual void show(){cout<<"lalala"<<endl;}//被覆盖

void show(int m){cout<<ma<<endl;}

protected:

int ma;

};

class Derive:public Base

{

public:

Derive(int a):mb(a),Base(a){}

~Derive(){}

void show(){cout<<"xixixi"<<endl;}//也成虚函数

private:

int mb;

};

int main(){

Derive d(2);

Base *= &d;

p->show();

//mov ecx,dword ptr[pb]     ecx放虚函数表的地址

//mov eax,dword ptr[ecx]    eax放第一个虚函数的地址

//call eax                       //动态绑定,运行时才知道这个值(虚函数)

cout<<typeid(p).name()<<endl;//Base*

cout<<typeid(*p).name()<<endl;//Derive

cout<<sizeof(Derive)<<endl;//8+4=12,这个下面就说~~~~~

}

派生类中函数名相同,参数列表同的函数自动被处理成 虚函数

类中有虚函数的时候,在 编译阶段 会生成一个vftable(虚函数表,放各种虚函数的地址) 类的对象共享一张表

虚函数指针vfptr(指向虚函数表入口地址)占4字节

→所以当类中有虚函数,类对象大小要加4字节。

 

派生类继承基类的虚函数表,但是由于覆盖原理,虚函数里的函数地址会变成自己的函数(会变成虚函数了)。

→所以,基类、派生类都有自己的虚函数表。

------------------------------------------------------------------------------------------------------------

(๑¯ิε ¯ิ๑) over~栗子全都来源老师上课内容,运行结果懒得截图所以直接写旁边了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值