2016-08-22 16:58:55 lhanchao 阅读数 447
  • C++语言基础视频教程

    C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过实践的方式,学会利用C++语言解决问题,具备进一步学习利用C++开发应用程序的基础。

    209769 人正在学习 去看看 贺利坚

一、复习基础

1、C++的继承方式属于多继承,即一个子类可以同时继承多个父类。

class 派生类:继承方式 基类名称,继承方式 基类名称,……
{
    //多个基类
}

2、派生类的生成过程
* 吸收基类成员;
* 改造基类成员;
* 添加新的成员。

二、访问控制

  • 类的访问方式有三种:public、protected、private;
  • 派生类中对于基类的成员访问有两种途径:
    (1)派生类中的新增成员对于从基类继承的成员的访问;
    (2)派生类外部(非类族内成员),通过派生类的对象访问从基类继承的成员。
  • 公有继承(public)
    当类的继承方式为公有继承时,原基类中的public、protected的成员访问属性不变,仍为public、protected;原基类中的private成员则不可直接访问。所谓的不可直接访问是指前面提到的两种途径都不可访问
  • 保护继承(protected)
    当类的继承方式为保护继承时,原基类中的public、protected的成员访问属性都变成protected;原基类中的private成员则不可直接访问。
  • 私有继承(private)
    当类的继承方式为私有继承时,原基类中的public、protected的成员访问属性都变成private;原基类中的private成员则不可直接访问。
    从表面上看protected和private继承方式是相似的,在直接派生类中,所有成员的访问属性都是相同的。但是,如果派生类作为新的基类继续派生时,二者的区别就出来了。
    例如,我们有Point类作为基类通过保护继承的方式派生出Line类,再由Line类派生出Rectangle类。当由Point类的public、protected的成员在Line中都变成了protected类型,再由Line通过私有继承的方式派生出Rectangle类,则原本Point中的public、protected的成员在Rectangle中变成了private类型。
    当Point类作为基类通过私有继承的方式派生出Line类,再由Line类派生出Rectangle类。当由Point类的public、protected的成员在Line中都变成了private类型,再由Line通过私有继承的方式派生出Rectangle类,则原本Point中的public、protected的成员在Rectangle中变成了不可直接访问的成员。

三、类型兼容规则

类型兼容规则是指,在需要基类对象的任何地方,都可以使用其公有派生类的对象进行替代。
通过公有继承,派生类得到了基类的除了构造函数和析构函数以外的一切成员,因此在需要使用基类的地方,都可以是用派生类进行替换,这也是多态性的基础之一。
类型兼容规则中所指的替代包括以下的情况:
* 派生类的对象可以隐含转换为基类对象
* 派生类的对象可以初始化基类的引用
* 派生类的指针可以隐含转换为基类的指针

#include <iostream>

using namespace std;

class Base0
{
public:
    void display()
    {
        cout<<"This is Base0"<<endl;
    }
};

class Base1:public Base0
{
public:
    void display()
    {
        cout<<"This is Base1"<<endl;
    }
};

class Derived:public Base1
{
public:
    void display()
    {
        cout<<"This is Derived"<<endl;
    }
};

void fun(Base0 *b)
{
    b->display();
}

int main()
{
    Base0 base0;
    Base1 base1;
    Derived derived;

    fun(&base0);
    fun(&base1);
    fun(&derived);

    return 0;
}

最终结果三个全部输出This is Base0

四、派生类的构造和析构函数

1、构造函数

在进行派生的过程中,基类的构造函数和析构函数并没有传给派生类,因此我们需要定义派生类的构造函数来初始化基类的成员对象和派生类新增加的成员对象。

什么时候需要给派生类显式的声明构造函数呢?
当对基类进行初始化时,需要调用基类的带有形参表(即有形参)的构造函数时,派生类必须声明构造函数
派生类构造函数的形式为:

派生类名::派生类名(参数表):基类名1(基类1的初始化参数表),基类名2(基类2的初始化参数表),...,基类名n(基类n的初始化参数表),成员对象1(成员对象1的初始化参数表),...,成员对象n(成员对象n的初始化参数表)
{
    构造函数的其他操作;
}

在构造函数的参数表中,需要对每个使用形参表的构造函数的基类,都需要给出初始化参数表,对于使用默认构造函数的基类,可以省略。
派生类的构造函数执行的过程如下:

  1. 调用各个基类的构造函数,调用的顺序为他们被继承时的声明的顺序;
  2. 对新增的成员对象进行初始化,调用顺序为他们在类中的声明顺序;
  3. 执行派生类的构造函数体中的内容

未完待续……

2019-08-19 20:10:55 weixin_45050225 阅读数 26
  • C++语言基础视频教程

    C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过实践的方式,学会利用C++语言解决问题,具备进一步学习利用C++开发应用程序的基础。

    209769 人正在学习 去看看 贺利坚

一、类的继承

1、共性与个性
表达不同类型事物之间共有的属性和行为
个性用于刻画每种事物特有的属性和行为
2、共性表示为父类(基类),个性表示为子类(派生类)
子类继承父类
基类派生出子类

二、继承的基本语法

1、继承表
一个子类可以同时继承0~多个父类,每个父类的继承方式可以相同也可以不同
class 子类:继承方式1 父类1,
继承方式2,父类2…
{

}
2、继承方式
public 公有继承:父类的特性可通过子类向外拓展
private 私有继承:父类的特性只能为子类所有
protected 保护继承:父类的特性只能在继承链内拓展

三、继承的特点

1、公共特点(所有继承都有的特点)
子类对象可以当作父类对象使用,子类对象与父类没有本质上的区别
子类的逻辑空间小于父类,物理空间要大于等于父类
子类对象 IS A 父类对象
2、向上和向下转换(造型)
从子类到父类:子类的指针或引用可以隐式转换成父类的指针或引用,这是一种缩小类型的转换,对于编译器来说是安全的
从父类到子类:父类的指针或引用不可以转化成子类的指针或引用,这是一种扩大类型的转换,在编译器看来是非常危险的
编译器仅仅是检查指针或引用的数据类型,而对实际引用的目标对象不关心(构成多态的基础)。
类型一致:父类的指针或引用实际的目标类型是否需要转换成实际的指针或引用由程序员自己决定
3、子类会继承父类的所有成员(公开、私有、保护)
4、子类会隐藏父类的同名成员
1、可以通过域限定符 父类::隐藏成员 进行访问父类中的隐藏成员
2、可以使用父类的指针或引用来指向子类对象,然后访问父类中的隐藏成员。
5、虽然子类中继承了所有父类中的成员,但不能访问父类中的私有成员。

继承方式影响访问控制

1、访问控制限定符:

访问限定符 内部 子类 外部 友元
public 1 1 1 1
protected 1 1 0 1
private 1 0 0 1

2、不同继承方式对基类成员的可见性

基类中的 在公有子类中变成 在保护子类中变成 在私有子类中变成
公有成员 公有成员 保护成员 私有成员
保护成员 保护成员 保护成员 保护成员
私有成员 私有成员 私有成员 私有成员
2013-04-10 21:00:10 zy_dreamer 阅读数 374
  • C++语言基础视频教程

    C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过实践的方式,学会利用C++语言解决问题,具备进一步学习利用C++开发应用程序的基础。

    209769 人正在学习 去看看 贺利坚
在过去的学习中,始终接触的单个类的继承,但是在现实生活中,一些新事物往往会拥有两个或者两个以上事物的属性,为了解决这个问题,C++引入了多重继承的概念,C++允许为一个派生类指定多个基类,这样的继承结构被称做多重继承

  举个例子,交通工具类可以派生出汽车和船连个子类,但拥有汽车和船共同特性水陆两用汽车就必须继承来自汽车类与船类的共同属性。

  由此我们不难想出如下的图例与代码:

  当一个派生类要使用多重继承的时候,必须在派生类名和冒号之后列出所有基类的类名,并用逗好分隔。

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(int weight = 0)
{
Vehicle::weight = weight;
}
void SetWeight(int weight)
{
cout<<"重新设置重量"<<endl;
Vehicle::weight = weight;
}
virtual void ShowMe() = 0;
protected:
int weight;
};
class Car:public Vehicle//汽车
{
public:
Car(int weight=0,int aird=0):Vehicle(weight)
{
Car::aird = aird;
}
void ShowMe()
{
cout<<"我是汽车!"<<endl;
}
protected:
int aird;
};

class Boat:public Vehicle//船
{
public:
Boat(int weight=0,float tonnage=0):Vehicle(weight)
{
Boat::tonnage = tonnage;
}
void ShowMe()
{
cout<<"我是船!"<<endl;
}
protected:
float tonnage;
};

class AmphibianCar:public Car,public Boat//水陆两用汽车,多重继承的体现
{
public:
AmphibianCar(int weight,int aird,float tonnage)
:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)
//多重继承要注意调用基类构造函数
{

}
void ShowMe()
{
cout<<"我是水陆两用汽车!"<<endl;
}
};
int main()
{
AmphibianCar a(4,200,1.35f);//错误
a.SetWeight(3);//错误
system("pause");
}

  上面的代码从表面看,看不出有明显的语发错误,但是它是不能够通过编译的。这有是为什么呢?
  这是由于多重继承带来的继承的模糊性带来的问题。

 



  先看如下的图示:

  在图中深红色标记出来的地方正是主要问题所在,水陆两用汽车类继承了来自Car类与Boat类的属性与方法,Car类与Boat类同为AmphibianCar类的基类,在内存分配上AmphibianCar获得了来自两个类的SetWeight()成员函数,当我们调用a.SetWeight(3)的时候计算机不知道如何选择分别属于两个基类的被重复拥有了的类成员函数SetWeight()。

  由于这种模糊问题的存在同样也导致了AmphibianCar a(4,200,1.35f);执行失败,系统会产生Vehicle”不是基或成员的错误。

  以上面的代码为例,我们要想让AmphibianCar类既获得一个Vehicle的拷贝,而且又同时共享用Car类与Boat类的数据成员与成员函数就必须通过C++所提供的虚拟继承技术来实现。

  我们在Car类和Boat类继承Vehicle类出,在前面加上virtual关键字就可以实现虚拟继承,使用虚拟继承后,当系统碰到多重继承的时候就会自动先加入一个Vehicle的拷贝,当再次请求一个Vehicle的拷贝的时候就会被忽略,保证继承类成员函数的唯一性

  修改后的代码如下,注意观察变化:

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(int weight = 0)
{
Vehicle::weight = weight;
cout<<"载入Vehicle类构造函数"<<endl;
}
void SetWeight(int weight)
{
cout<<"重新设置重量"<<endl;
Vehicle::weight = weight;
}
virtual void ShowMe() = 0;
protected:
int weight;
};
class Car:virtual public Vehicle//汽车,这里是虚拟继承
{
public:
Car(int weight=0,int aird=0):Vehicle(weight)
{
Car::aird = aird;
cout<<"载入Car类构造函数"<<endl;
}
void ShowMe()
{
cout<<"我是汽车!"<<endl;
}
protected:
int aird;
};

class Boat:virtual public Vehicle//船,这里是虚拟继承
{
public:
Boat(int weight=0,float tonnage=0):Vehicle(weight)
{
Boat::tonnage = tonnage;
cout<<"载入Boat类构造函数"<<endl;
}
void ShowMe()
{
cout<<"我是船!"<<endl;
}
protected:
float tonnage;
};

class AmphibianCar:public Car,public Boat//水陆两用汽车,多重继承的体现
{
public:
AmphibianCar(int weight,int aird,float tonnage)
:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)
//多重继承要注意调用基类构造函数
{
cout<<"载入AmphibianCar类构造函数"<<endl;
}
void ShowMe()
{
cout<<"我是水陆两用汽车!"<<endl;
}
void ShowMembers()
{
cout<<"重量:"<<weight<<"顿,"<<"空气排量:"<<aird<<"CC,"<<"排水量:"<<tonnage<<"顿"<<endl;
}
};
int main()
{
AmphibianCar a(4,200,1.35f);
a.ShowMe();
a.ShowMembers();
a.SetWeight(3);
a.ShowMembers();
system("pause");
}

最后运行结果如下:

 

 

2019-08-19 19:02:12 cbnzww 阅读数 22
  • C++语言基础视频教程

    C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过实践的方式,学会利用C++语言解决问题,具备进一步学习利用C++开发应用程序的基础。

    209769 人正在学习 去看看 贺利坚

一、类的继承

  • 共性与个性
    • 共性,表达不同类型事务之间共有的属性和行为
    • 个性,用于刻画每种事物持有的属性和行为。
  • 共性表示为父类基类),个性表示为子类派生类
    • 子类继承自父类
    • 基类派生出子类

二、继承的基本语法

  • 继承表
    • 一个子类可以同时继承零到多个父类,每个父类的继承方式可以相同也可以不同
class 子类:继承方式1 父类1,继承方式2	父类2,...
{

}
  • 继承方式
    • public 共有继承:父类的特性可通过子类向外扩展
    • private 私有继承:父类的特性只能为子类所有
    • protected 保护继承:父类的特性只能在继承链内扩展

三、继承的基本特点

  • 公共特点所有继承都具备的特点):
    • 子类对象可以当做父类对象使用
    • 子类对象与父类对象没有本质上的区别
    • 子类的逻辑空间小于父类
    • 物理空间大于等于父类
    • 子类对象 IS A 父类对象
  • 向上和向下转换造型):
    • 从子类到父类,子类的指针或引用可以隐式转换成父类的指针或引用,这是一种缩小类型的转换,对于编译器来说是安全的;(父类指针指向子类对象,是安全的)
    • 从父类到子类,父类的指针或引用不可以转换成子类的指针或引用,这是一种扩大类型的转换,在编译器中看来是危险的。(子类的指针指向父类的对象,不安全)
    • 编译器仅仅是检查指针或引用的数据类型,而对实际引用的目标对象不关心(构成多态的基础)
  • 类型一致
    • 父类的指针或引用类型是否需要转换成实际的指针或引用由程序员自己决定。
  • 子类会继承父类的所有成员(公开、私有、保护)
  • 子类会隐藏父类的同名成员,但也可以通过方法访问父类中的隐藏成员
    • 可以通过域限定符 父类::隐藏成员,进行访问父类中的隐藏成员
    • 可以使用指针或引用来指向子类对象,然后访问父类中的隐藏成员
  • 虽然子类继承所有父类中的成员,但不能访问父类中的私有成员

四、继承方式影响访问控制

  • 访问控制限定符
访问控制限定符 内部 子类 外部 友元
public 可以访问 可以访问 可以访问 可以访问
private 可以访问 可以访问 不可以访问 可以访问
protected 可以访问 不可以访问 不可以访问 可以访问
  • 继承方式的影响范围
父类(基类)中 在公有子类中变成 在保护子类中变成 在私有子类中变成
public 公有成员 保护成员 私有成员
private 保护成员 保护成员 保护成员
protected 私有成员 私有成员 私有成员
2013-10-21 14:24:16 oksirzhang 阅读数 433
  • C++语言基础视频教程

    C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过实践的方式,学会利用C++语言解决问题,具备进一步学习利用C++开发应用程序的基础。

    209769 人正在学习 去看看 贺利坚

C++类继承中总共可以通过三个方式来实现,包括:公有继承(public),私有继承(private),保护继承(protected) 等。

C++编程语言的应用范围比较广泛,能够以一种简单灵活的方式帮助开发人员实现许多功能。在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生。 从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

例:单继承的定义

  1. class B:public  
  2. {   
  3. < 派生类新定义成员> 
  4. };  
  5. 多继承的定义  
  6. class C:public A,private B  
  7. {   
  8. < 派生类新定义成员>   
  9. }; 

注:如果在基类前不写访问控制符,则默认为私有的

派生类共有三种C++类继承方式:公有继承(public),私有继承(private),保护继承(protected)

公有继承(public)

基类的公有成员和保护成员可以作为其派生类的公有成员和保护成员

派生类的成员函数可以访问基类中的公有成员和保护成员,无法访问基类中的私有成员

派生类的对象可以访问基类的公有成员

私有继承(private)

基类的公有成员和保护成员都作为其派生类的私有成员

在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承

保护C++类继承(protected)

基类的所有公有成员和保护成员都成为派生类的保护成员

基类的公有成员和保护成员只能被它的直接派生类成员函数或友元访问

构造函数和析构函数不能被继承

因此构造派生类的对象时,需要对基类数据成员.新增数据成员和成员对象的数据成员进行初始化

派生类构造函数的参数表部分既需要包含子类某些数据成员的初始值,也要包含基类的数据成员的初始值

如果基类没有默认的构造函数,那么派生类必须具有给基类构造函数提供参数的构造函数

派生类构造函数一般语法如下:

  1. 派生类名::派生类名(参数总表)  
  2. :基类名1(参数表1),...,基类名n(参数表n)  
  3. {  
  4. 初始化语句  

当基类有多个构造函数时,编译器根据派生类构造函数为基类构造函数提供的参数初始化列表中的参数类型来确定调用哪个构造函数

派生类的析构函数应当首先对派生类新增普通成员进行清理

然后对派生类新增的对象成员进行清理

最后是对所有从C++类继承来的成员进行清理


C++ 继承

阅读数 11

C++多态和继承

阅读数 56

没有更多推荐了,返回首页