设为首页 加入收藏

TOP

c++三大特性之继承(一)
2016-12-06 20:24:47 】 浏览:549
Tags:三大 特性 继承

1、概念:

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。

一个新类从已有的类中获得其已有的特性称为继承,被继承的称为父类(Base class)或基类,新产生的类称为派生类或子类。

2、继承的方式:

继承权限规则表

继承方式

基类的public成员

基类的protected成员

基类的private成员

继承引起的访问控制变化

Public

Public

Protected

不可见

基类成员在派生类中访问权限不变

Protected

Protected

Protected

不可见

基类的非私有成员成为子类的保护成员

Private

Private

Private

不可见

基类的所有成员成为子类的私有成员

class Base

{

public:

Base()

{

_pri = 1;

_pro = 2;

_pub = 3;

}

private:

int _pri;

protected:

int _pro;

public:

int _pub;

};

class Derived1 :public Base

{

public:

Derived1()

{

_d1_pri = 4;

_d1_pro = 5;

_d1_pub = 6;

}

void showd()

{

_pub = 0; // 仍为public成员

_pro = 2; // 仍为protected成员

//_pri = 3; // 父类私有成员对子类 不可见

}

private:

int _d1_pri;

protected:

int _d1_pro;

public:

int _d1_pub;

};

void TestPublic()

{

Base b;

b._pub = 1;

//b._pro = 2; // 父类对象不可访问父类保护成员

//b._pri = 3; // 父类对象不可访问父类私有成员

Derived1 d1;

d1._pub = 1; // 子类对象可以访问父类公有成员

//d1._pro = 2; //子类对象不可访问父类保护成员

//d1._pri = 3; // 子类对象不可访问父类私有成员

d1._d1_pub = 4;

}

// protected 保护继承

class Derived2 :protected Base

{

public:

Derived2()

{

_d2_pri = 4;

_d2_pro = 5;

_d2_pub = 6;

}

void showd()

{

_pub = 1; // 变为子类的protected成员

_pro = 2; // 仍为protected成员

//_pri = 3; // 父类私有成员对子类不可见

}

private:

int _d2_pri;

protected:

int _d2_pro;

public:

int _d2_pub;

};

void TestProtected()

{

Base b;

b._pub = 1;

//b._pro = 2; // 父类对象不可访问父类保护成员

//b._pri = 3; // 父类对象不可访问父类私有成员

Derived2 d2;

//d2._pub = 1; // 父类的public成员权限被修改为protected,子类对象不可访问

//d2._pro = 2; //子类对象不可访问父类保护成员

//d2._pri = 3; // 子类对象不可访问父类私有成员

d2._d2_pub = 4;

}

// private私有继承

class Derived3 :private Base

{

public:

Derived3()

{

_d3_pri = 4;

_d3_pro = 5;

_d3_pub = 6;

}

void showd()

{

_pub = 1; // 变为子类的privite成员

_pro = 2; // 变为子类的privite成员

//_pri = 3; // 父类私有成员对子类不可见

}

private:

int _d3_pri;

protected:

int _d3_pro;

public:

int _d3_pub;

};

void TestPrivate()

{

Base b;

b._pub = 1;

//b._pro = 2; // 父类对象不可访问父类保护成员

//b._pri = 3; // 父类对象不可访问父类私有成员

Derived3 d3;

//d3._pub = 1; // 父类的public成员权限被修改为private,子类对象不可访问

//d3._pro = 2; // 父类的protected成员权限被修改为private,子类对象不可访问

//d3._pri = 3; // 子类对象不可访问父类私有成员

d3._d3_pub = 4;

}

3、继承又可以分为单继承,多继承,钻石继承(又叫菱形继承),现在来谈论下三种情况下派生类的布局:

(1)单继承:

#include

using namespace std ;

class Base

{

public:

Base(int a= 0, int b= 1):_a(a),_b(b)

{

cout << "我是基类的构造函数" <

\

为啥子类对象赋值给父类对象可以,父类对象赋值给子类对象不可以

原因就是子类对象赋值给父类对象时,子类对象发生对象切片,将子类对象的父类部分赋值给父类对象,但是父类对象赋值给子类对象时,没有办法对子类自己的成员赋值,所以父类对象赋值给子类对象不可以。

(2)多继承

#include

using namespace std ;

class Base1

{

public:

Base1(int a= 0, int b= 1):_a(a),_b(b)

{

cout << "我是基类的构造函数" <从结果我们能分析,先调用base2的构造函数,在调用base1的构造函数,最后调用自己的构造函数,析构函数相反,这就说明先继承谁先调用谁的构造函数,子类的成员布局如下:

\

(3) 菱形继承:#include

using namespace std ;

class Base1

{

public:

Base1(int a= 0, int b= 1):_a(a),_b(b)

{

cout << "我是基类的构造函数" <

\

派生类Derived对象d成员布局如下:

\

从派生类对象成员布局可以看出,派生类对象继承了两份Base类成员,所以d._a访问不明确,因此虚继承的语法出现了。#include

using namespace std ;

class Base1

{

public:

Base1(int a= 0, int b= 1):_a(a),_b(b)

{

cout << "我是基类的构造函数" <

\

从结果分析我们能看出只是继承了一份基类,但是对象的大小变成了28,说明派生类中有8个字节是系统给我们自动加上的。

\

从图中我们可以看出确实只是继承了一份继承,但是基类的布局和原来的布局不一样,现在基类在最低下,Derived1中插入一个指针,指向一个表,表中存放了Deriverd1相对于基类的偏移量,Derived2也存放一个指针,同样指向一个表,这个表中同样存放了Derived2相对于基类的偏移量。从图中我们看出虚继承内存不一样的机制解决了变量的二义性问题。4.继承综合案例:#include

using namespace std ;

namespace

{

class Base

{

public:

Base(int a):_a(a)

{

cout << "我是基类的构造函数" <

\

5.继承注意点:(1)父类的构造、析构、拷贝构造、重载赋值运算符,友元函数不能继承。(2)基类没有缺省构造函数

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c++栈的简单实现 下一篇AdaBoost C++实现

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目