11 继承,多重继承与虚继承

1.继承其实就是在一个类的基础上扩展新的功能的类型。

#include <iostream>


using namespace std

class Animal {

private:

int age;


public:

void eat() {

age = 88;

cout <<"animal eat" << endl;

};

};


// Animal叫作Human的父类, HumanAnimal的子类

// 继承是可以多层继承的,基类是最底层的类。 子类的子类以下级别的类叫派生类.

class Human : publicAnimal { // Human继承了Animal,完全具有Animal类对象的功能

public:

void think() { //扩展的功能

cout <<"human think" << endl;

}

};


int main(void)

{

Human h;


h.eat();

h.think();

return 0;

}


注意:继承时,父类的私有成员也是有继承过来的,只是子类不能直接访问父类的私有成员

一个对象/类型的大小,只算属性成员的大小,函数成员不算大小的。同时也需注意它的祖先类的大小。

创建一个子类对象时,父类也需创建一个对象,子类对象是由父类对象与它自己的属性成员组合成的.


友员的关系没有继承的

public继承时:

父类的公有成员在子类里的权限还是public

父类的受保护成员在子类里的权限还是protected

父类的私有成员在子类里不能直接访问


protected继承:

父类的公有成员在子类里的权限是protected

父类的受保护成员在子类里的权限还是protected

父类的私有成员在子类里不能直接访问


private继承:

父类的公有成员在子类里的权限是private

父类的受保护成员在子类里的权限是private

父类的私有成员在子类里不能直接访问



2.继承时,创建子类对象时也会创建它的父类对象。子类和父类的构造函数都会触发.


#include <iostream>


using namespace std;


class Animal {

public:

Animal() {

cout << "animal init " << endl;

}

~Animal() {

cout << "animal exit " << endl;

}

};


class Human : public Animal {

public:

Human() {

cout << "human init " << endl;

}

~Human() {

cout << "human exit " << endl;

}

};


int main(void)

{

Human *h;


h = new Human;


cout << "#################" << endl;

delete h;

return 0;

}

编译执行时的输出:

[root@localhost 11inherit]# ./a.out

animal init

human init

#################

human exit

animal exit


从表面上看当创建对象时,父类构造先执行,然后才是子类的构造函数执行。

反汇编来看,可以发现其实是子类的构造函数先执行,在子类的构造函数里再调父类的构造函数.

子类的析构函数先执行,在子类的析构函数里再调用父类的析构函数.

当父类的构造函数必须传参数时,必须在子类的构造函数的函数体加上”: 父类构造函数名(参数)”来调用父类的构造函数.


class Animal {

private:

int num;

public:

Animal(int num) {

this->num = num;

cout << "animal init num = " << num <<endl;

}

~Animal() {

cout << "animal exit " << endl;

}

};


class Human : public Animal {

private:

int hh;

public:

Human(int num, int n) : hh(n), Animal(num){

cout << "human init hh = " << hh <<endl;

}

~Human() {

cout << "human exit " << endl;

}

};


int main(void)

{

Human *h;


h = new Human(123, 7788);

cout << "#################" << endl;

delete h;

return 0;

}


构造函数的”:”可以调用父类的构造函数(只能调用父类的构造函数,不能越级), 也可以用于内部属性成员进行初始化.



3. 多重继承

通过继承多个父类扩展出一个新的类型。


class AA {

...

};


class BB {

..

};


class AB : public AA, public BB {

...

};


多重继承也会带来新的问题,如下代码:


//基类

class Object {

public:

Object() {

cout << "object init" << endl;

}

};


class A : public Object {

//当创建A的对象时,Object也需创建一个对象

};


class B : public Object {

//当创建B的对象时,Object也需创建一个对象

};


class AB : public A, public B {

//创建AB的对象时,AB都需要创建一个对象,但会有两个Object对象

};


int main(void)

{

AB a;


return 0;

}


要解决重复创建同一基类的对象时,可以使用虚继承.

Class A : virtual public Object {


};

Class B : virtual public Object {


};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值