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基类和派生类
背景:对基类和派生类有更清晰的认识. 从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 .但继承并不仅仅是类的复用.当创建了一个派生类的对象时,该类包含了一个基类的子对 ...
随机推荐
- Oracle 表的连接方式(1)-----Nested loop join和 Sort merge join
关系数据库技术的精髓就是通过关系表进行规范化的数据存储,并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理. 表的三种关联方式: nested loop:从A表抽一条记录,遍历B表查找匹配 ...
- 如何在SAE上使用DjangoUeditor
之前的一个项目是部署到SAE上的,其中富文本编辑器使用到了Ueditor,对于Django有一个开源项目DjangoUeditor可以简化继承过程,直接引用app就可以使用.但是不支持SAE的文件上传 ...
- CentOS 6.4 安装搭建 Scrapy 0.22 环境
一.安装Python2.7.6 更新CentOS lib库文件 yum -y update 安装开发工具包 yum groupinstall -y development 安装扩展包 yum inst ...
- 在 SQL Server 中的网络数据库文件的支持说明
其实就是一个学员问SQL Server 是否能存放的于NAS(UAC 的路径下). 官方的回答简略版本为:可以,需要满足一些强制性的硬件要求.但需要考虑一系列的性能的问题. http://suppor ...
- 表达式语言之ongl表达式
OGNL的全称是Object Graph Navigation Language(对象图导航语言),它是一种强大的表达式语言,让你通过简单一致的表达式语法来读取和设置Java对象的属性值,调用对象的方 ...
- 微软职位内部推荐-Sr SDE for Win Apps Ecosystem
微软近期Open的职位: Job posting title: Senior Software Design Engineer Location: China, Beijing Level: 63 D ...
- WPF中使用ValueConverter来实现“范围条件触发器”
在WPF中,我们知道界面层可以通过Trigger触发器实现“条件”——“赋值”的功能 属性触发器Property Trigger:当Dependency Property的值发生改变时触发.数据触发器 ...
- Graduate Summer School: Deep Learning, Feature Learning
http://www.ipam.ucla.edu/programs/summer-schools/graduate-summer-school-deep-learning-feature-learni ...
- MVC4 错误: 检测到有潜在危险的 Request.Form值
说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止.该值可能指示存在危及应用程序安全的尝试,如跨站点脚本攻击.若要允许页面重写应用程序请求验证设置,请将 httpRuntime ...
- texCUBE() to CubemapSampler.Sample()
update dx9 to dx11 refers to CUBEMAP sampler texCUBE(CubeMpaSampler,normal) maybe change to Cubema ...