C++:基类和派生类
4.1 派生类的声明
继承实例如下:
class Person{ //声明基类Person
public:
void print()
{
cout<<"name:"<<name<<endl;
cout<<"age:"<<age<<endl;
cout<<"sex:"<<sex<<endl;
}
protected:
string name;
int age;
char sex;
};
class Employee:public Person{ //声明派生类Employee公有继承了基类Person
public:
void print1() //新增成员函数
{
print();
cout<<"department:"<<department<<endl;
cout<<"salary:"<<salary<<endl;
}
private:
string department; //新增数据成员
int salary; //新增数据成员
};
声明一个派生类的一般格式是:
Class 派生类 : [继承方式] 基类名{
派生类新增加的数据成员和成员函数
};
说明: 基类名为声明的父类,派生类为子类
继承方式分三种:public、private、protected
4.1.3 派生类的构成
(1)派生类从基类接收成员
在C++的类继承中,派生类把基类的全部成员函数(除了构造函数和析构函数)接收过来
(2)调整从基类接收的成员
一方面改变基类成员在派生类中的访问属性,主要通过声明时的继承方式来控制;
另一面派生类可以对基类中的函数进行重定义,即覆盖基类中的同名函数。
(3)在派生类中新增成员
新增的成员可以是数据成员,也可以是成员函数
注意:基类的构造函数和析构函数不能被继承,一般需要派生类声明自己的构造函数和析构函数。
4.1.4 基类成员在派生类中的访问属性
派生类可以继承除了构造函数与析构函数之外的成员,但是这些成员的访问属性在派生过程中
是可以调整的。从基类继承来的成员在派生类中的访问属性是由继承方式控制的。
类的继承方式有public公有继承、protected保护继承、private私有继承三种。不同的继承方式
导致不同访问属性的基类成员在派生类在派生类中的访问属性也有所不同。
在派生类中,从基类继承来的成员可以按访问属性划分为四种:不可直接访问、公有public、
保护protected、私有private。
表4.1 基类成员在派生类中的访问属性
————————————————————————————————————————————————
基类中的成员| 在公有派生类中的访问属性| 在私有派生类中的访问属性 | 在保护派生类中的访问属性
————————————————————————————————————————————————
私有成员 | 不可直接访问 | 不可直接访问 | 不可直接访问
公有成员 | 公有 | 私有 | 保护
保护成员 | 保 | 私有 | 保护
————————————————————————————————————————————————
从表4.1中可以归纳出以下几点
(1) 基类中的私有成员。
无论哪种继承方式,基类中的私有成员不允许派生类继承,即在派生类中是不可直接访问的。
(2) 基类中的公有成员
a.当类的继承方式为公有继承时,基类中的所有公有成员在派生类中仍以公有成员的身份出现。
b.当类的继承方式为私有继承时,基类中的所有公有成员在派生类中仍以私有成员的身份出现
c.当类的继承方式为保护继承时,基类中的所有公有成员在派生类中仍以保护成员的身份出现。
(3)基类中保护成员。
a.当类的继承方式为公有继承时,基类中的所有公有成员在派生类中仍以保护成员的身份出现。
b.当类的继承方式为私有继承时,基类中的所有公有成员在派生类中仍以私有成员的身份出现。
c.当类的继承方式为保护继承时,基类中的所有公有成员在派生类中仍以保护成员的身份出现。
4.1.5 派生类对基类成员的访问规则
基类的成员可以有public、protected、private三种访问属性,基类的成员函数可以访问基类中其它
成员,但是在基类外通过基类的对象,就只能访问基类的公有成员。
同样,派生类的成员也可以有public、protected、private三种访问属性,派生类的成员函数可以访问
派生类中自己增加的成员,但是在派生类外通过基类的对象,就只能访问该派生类的公有成员
。
派生类对基类成员的访问形式主要有以下两种:
(1)内部访问。由派生类中新增的成员函数对从基类继承来的成员的访问。
(2)对象访问。在派生类外部,同过派生类的对象对从基类继承来的成员的访问。
表4.2 私有继承的访问规则(private)
-----------------------------------------------------------------
基类中的成员 | 稀有成员 | 共有成员 |保护成员
-----------------------------------------------------------------
内部访问 | 不可访问 | 可访问 | 可访问
对象访问 | 不可访问 | 不可访问 | 不可访问
-----------------------------------------------------------------
//例4.1私有继承的访问规则举例1
#include<iostream>
using namespace std;
class Base{ //声明基类
public:
void setx(int n) //正确,成员函数setx可以访问本类中的私有成员x
{
x = n;
}
void showx() //正确,成员函数showx可以访问本类中的私有成员x
{
cout<<x<<endl;
}
private:
int x;
};
class Derived:private Base{ //声明基类Base的私有派生类Derived
public:
void setxy(int n,int m)
{
setx(n); //正确,基类的setx函数在派生类中为私有成员,派生类中的成员函数可以访问
y = m; //正确,成员函数setxy可以访问本类中的私有成员y
}
void showxy()
{
//cout<<x; //错误,派生类中的成员函数不能直接访问基类中的私有成员
showx(); //正确,基类的showx函数在派生类中为私有成员,派生类中的成员函数可以访问
cout<<y<<endl; //正确,成员函数showxy可以直接访问本类中的私有成员y
}
private:
int y;
};
int main()
{
Derived obj;
//obj.setx(10); //错误,setx在派生类中为私有成员,派生类对象不能直接访问。
//obj.showx(); //错误,showx在派生类中为私有成员,派生类对象不能直接访问。
obj.setxy(,); //正确,setxy在本类Derived中为公有成员,派生类对象能直接访问。
obj.showxy(); //正确,showxy在本类Derived中为公有成员,派生类对象能直接访问
return ;
}
/*
说明:可见基类中的私有成员既不能被派生类的对象访问,也不能被派生类中的成员函数访问。即不可访问成员,
因此,在设计基类时,总要为它的私有数据提供公有成员函数,如在本例的成员函数showx等,以便使派
生类可以间接访问这些成员。
*/
//私有继承的访问规则举例2
#include<iostream>
using namespace std;
class Base{ //声明基类Base
public:
void seta(int sa) //正确,成员函数seta可以访问本类中的保护成员a
{
a = sa;
}
void showa()
{
cout<<"a="<<a<<endl; //正确,成员函数showa可以访问本类中的保护成员a
}
protected:
int a;
};
class Derive1:private Base{ //声明基类Base的私有派生类Derive1
public:
void setab(int sa,int sb)
{
a = sa; //正确,a在派生类中为私有成员,派生类成员函数可以访问
b = sb; //正确,b在派生类中为保护成员,派生类成员函数可以访问
}
void showab()
{
showa();
//cout<<"a="<<a<<endl; //正确,a在派生类中为私有成员,派生类成员函数可以访问
cout<<"b="<<b<<endl; //正确,a在派生类中为保护成员,派生类成员函数可以访问
}
protected:
int b;
};
class Derive2:private Derive1{ //声明类Derive1的私有派生类Derive2
public:
void setabc(int sa,int sb,int sc)
{
setab(sa,sb); //正确,setab函数在派生类Derive2中为私有成员,成员函数setabc可以访问
c = sc;
}
void showabc()
{
showab(); //正确,showab函数在派生类Derive2中为私有成员,成员函数showabc可以访问
//cout<<"a="<<a<<endl; //错误,a在类Derive2中为不可直接访问成员
//cout<<"b="<<b<<endl; //正确,b在类Derive2中为私有成员
cout<<"c="<<c<<endl; //正确,c在类Derive2中为私有成员
}
private:
int c;
};
int main()
{
Base op1;
op1.seta();
op1.showa();
Derive1 op2;
op2.setab(,);
op2.showab();
Derive2 op3;
op3.setabc(,,);
op3.showabc();
return ;
}
/*
说明:经过了私有继承后,所有基类中的成员都成为了派生类的私有成员或不可直接访问的
成员,如果进一步派生的话,基类的全部成员都无法在新的派生类中被访问。因此,
私有继承之后,基类的成员无法在以后的派生类中在发挥作用,实际是相当于中止了
基类功能的继承派生,出于这种原因,私有继承的实际应用很少。
*/
表4.2 保护继承的访问规则(protected)
-----------------------------------------------------------------
基类中的成员 | 稀有成员 | 共有成员 |保护成员
-----------------------------------------------------------------
内部访问 | 不可访问 | 可访问 | 可访问
对象访问 | 不可访问 | 可访问 | 不可访问
-----------------------------------------------------------------
//例 4.4 保护继承的访问规则
#include<iostream>
using namespace std;
class Base{
public:
int z;
void setx(int i)
{
x = i;
}
int getx()
{
return x;
}
private:
int x;
protected:
int y;
};
class Derived:protected Base{
public:
int p;
void setall(int a,int b,int c,int d,int e,int f );
void showall();
private:
int m;
protected:
int n;
};
void Derived::setall(int a,int b,int c,int d,int e,int f)
{
//x = a;//错误,在派生类Derived中,x为不可直接访问成员,但是可以通过成员函数间接访问
setx(a);
y = b; //正确,在派生类Derived中,Y仍是保护成员,派生类成员函数能访问它
z = c; //正确,在派生类Derived中,Y仍是保护成员,派生类成员函数能访问它
m = d;
n = e;
p = f;
}
void Derived::showall()
{
//cout<<"x="<<x<<endl; //错误,在派生类Derived中,x为不可直接访问成员
cout<<"x="<<getx()<<endl;//正确,函数getx在派生类Derived中为保护成员,派生类成员函数可以访问
cout<<"y="<<y<<endl; //正确,y在派生类Derived中为保护成员,派生类成员函数可以访问
cout<<"z="<<z<<endl; //正确,z在派生类Derived中为保护成员,派生类成员函数可以访问
cout<<"m="<<y<<endl; //正确,m在派生类Derived中为私有成员,派生类成员函数可以访问
cout<<"n="<<n<<endl; //正确,n在派生类Derived中为保护成员,派生类成员函数可以访问
}
int main()
{
Derived obj;
obj.setall(,,,,,);
obj.showall();
//cout<<"y="<<obj.y<<endl; //错误,y为派生类Derived的保护成员,派生类对象不能直接访问它
cout<<"p="<<obj.p<<endl; //正确,p为派生类Derived的公有成员,派生类对象可以直接访问它 return ;
}
/*
说明:例中的派生类Derived有基类Base保护派生出来,所以基类Base中的私有数据成员x在保护派生类
Derived中是不可直接访问的,因此派生类成员函数setall和showall不能访问它。基类Base中的
保护数据成员y在保护派生类Derived中仍是保护成员,因此派生类成员函数setall和showall能够
访问它,但是派生类Derived的对象obj不能访问它。派生类Derived的数据成员p是公有成员,所以
派生类Derived的对宪法obj可以访问它。
*/
表4.2 公有继承的访问规则(public)
-----------------------------------------------------------------
基类中的成员 | 稀有成员 | 共有成员 |保护成员
-----------------------------------------------------------------
内部访问 | 不可访问 | 可访问 | 可访问
对象访问 | 不可访问 | 可访问 | 不可访问
-----------------------------------------------------------------
//例4.3 公有继承的访问规则
#include<iostream>
using namespace std;
class Base{
public:
void setxy(int m,int n)
{
x = m;
y = n;
}
void showxy()
{
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
private:
int x;
protected:
int y;
};
class Derived:public Base{ //声明基类Base的公有继承类Derived
public:
void setxyz(int m,int n,int l)
{
setxy(m,n); //函数setxy在派生类中是public成员,派生类成员函数可以访问
z = l;
}
void showxyz()
{
//cout<<"x="<<x<<endl; //错误,x在类Derived中为不可直接访问成员
//showxy(); //函数showxy在派生类中是public成员,派生类成员函数可以访问
cout<<"y="<<y<<endl; //正确,y在类Derived中仍为protected成员,派生类成员函数可以访问
cout<<"z="<<z<<endl;
}
private:
int z;
};
int main()
{
Derived obj;
obj.setxyz(,,);
obj.showxy();//正确,函数showxy在类Derived中为公有成员,派生类对象也可以直接访问 //obj.y=60; //错误,y在类Derived中仍为protected成员,派生类对象不可以访问
obj.showxyz();
return ;
}
/*
说明:例中类Derievd有类Base公有派生出来,所以类Base中的两个公有成员函数setxy和showxy在
公有派生类中仍是公有成员。因此,它们可以分别被派生类的成员函数showxyz和派生类对象
obj直接访问。基类中数据成员x是私有的,它在派生类中不能直接访问的,所以在成员函数
showxyz中对x的访问是错误的。基类Base中的数据成员y是保护成员,它在公有派生类中仍是
保护成员,所以在派生类成员函数showxyz中对y的访问是正确的,但是派生类的对象不能访问。
*/
C++:基类和派生类的更多相关文章
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- (转) C++中基类和派生类之间的同名函数的重载问题
下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...
- c++中基类与派生类中隐含的this指针的分析
先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...
- C++学习21 基类和派生类的赋值
在C/C++中,经常会发生数据类型转换,例如整型数据可以赋值给浮点型变量,在赋值之前,先把整型数据转换为浮点型:反过来,浮点型数据也可以赋值给整型变量. 数据类型转换的前提是,编译器知道如何对数据进行 ...
- 基类和派生类--this
基类指针在程序运行的时候的确指向的是一个派生类的对象,但指针的类型仍然是基类指针.C++是一种强类型语言,因此不能用基类指针类型的指针直接调用派生类:而且,同一个类可能有多种不同的派生类,因此不知道实 ...
- C++:基类与派生类对象之间的赋值兼容关系
4.5 基类与派生类对象之间的赋值兼容关系 在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量. 在赋值之前,先把整型数据转换为双精度型数据,然后再把它双精度型变量. ...
- C++基类和派生类之间的转换
本文讲解内容的前提是派生类继承基类的方式是公有继承,关键字public 以下程序为讲解用例. #include<iostream> using namespace std; class A ...
- c++,派生类对象可以对基类赋值,基类对派生类不可以赋值
派生类对象可以对基类对象赋值,赋值时属于派生类独有的部分就舍弃不用. #include <iostream> using namespace std; class DemoA { publ ...
- Java基类和派生类
背景:对基类和派生类有更清晰的认识. 从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 .但继承并不仅仅是类的复用.当创建了一个派生类的对象时,该类包含了一个基类的子对 ...
随机推荐
- DBCC Check
DBCC CHECKDB 可以完成两个任务 (1)检查数据库里有没有损坏发生 (2)尽力修复数据库损坏,是数据能重新被正常访问 DBCC 下列步骤执行下列操作 1.检查一些关键性的表 sysalocu ...
- ASP.NET Web – 输入的有效性验证
下面这个示例显示了与文本框textFirstname相关的验证控件RequiredFieldValidator.所有的验证控件都有ErrorMessage和ControlToValidate属性.如果 ...
- linux作业六——进程的描述和进程的创建
进程的描述和进程的创建 一.进程描述符task_struct 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 代码关键点: 1.Struct list_hea ...
- 客户端通过spice-gtk实现USB重定向
1.安装必要的工具: sudo apt-get install build-essential autoconf git-core intltool 2.安装必要的依赖包: -dev libxfixe ...
- android 开发:讯飞的离线命令识别器官方demo使用及demo下载
场景:使用本地构建语法,离线识别命令词. 修改文件AsrDemo.java mLocalGrammar 修改为你自己的语法 mAsr.setParameter(SpeechConstant.GRAM ...
- Z480联想笔记本突然没有了声音
这几天笔记本突然没有了声音,重启几次都没有效果. 1.检查了声卡驱动,没有发现问题: 2.检查是否设置了静音,没有问题: 有人说重装驱动,懒得重装,于是下面的一个操作给解决了: 在“设备管理器”中找到 ...
- 开启VMware Esxi的SSH远程登录
1.在服务器的配置页面中开启 按[F2],输入密码,进入配置页面,选择troubleshooting options,选择EnableSSH 即可. 2.在VMware Client中开启 进入:配置 ...
- redis window环境下的安装地址
https://github-cloud.s3.amazonaws.com/releases/3402186/25358446-c083-11e5-89cb-61582694855e.zip?X-Am ...
- 以“图片渐入渐出”为例讲述jQuery插件的具体实现
首先声明,此代码以网友“斯迈欧”原创作为此例的讲解: 在这之前我们先看看我们要做的效果是什么样的: 解析下面的样式:我们要图片在过“一定时间”后自动切换,在右下角处有小方块似数字1,2,3,4,这些数 ...
- EBP的妙用[无法使用ESP定律时]
1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...