一、面向对象的程序设计语言
编辑源程序生成cpp文件——编译后生成obj文件——连接后生成exe文件
注释添加:选中内容,按Ctrl+Shift+c可以快速注释代码
注释撤销:选中内容,按Ctrl+Shift+x可以快速撤销代码
二、常量:其值在程序运行过程中保持不变
格式:Const 数据类型 常量名字
三、变量:先定义后使用
格式:类型 变量名(int i_area = 0,i_length = 0,i_width = 0;)
变量名由数字、字母、下划线组成;第一个字符必须是字母或者下划线;不能使用保留字
变量的存储以二进制形式存储,数值以补码形式表示(正数的补码与原码相同,负数的补码为绝对值的原码各位取反再加1)
1、int:整型;unsigned:正整型;char:单字符;转义字符:以\开头;字符串常量:"";实型常量:(1)十进制小数:必须有小数点,或在结尾加上f/F、(2)指数形式(a E n)(a为十进制小数,n为十进制整数);实型变量(分三类:单精度float、双精度double、长双精度long double)
2、字符常量占一个字节的内存空间;字符串在内存中的存储会自动生成一个结束标志“\0”,一个汉字占两个字节
3、字符可参与算术运算 (a:65,97)
4、整型、实型、字符型数据可以混合使用
5、自动类型转换:级别高的数据类型可以自动接受级别低的数据类型(long double、double、float、unsigned long、long、unsigned int、int、other type)
6、强制类型转化 :(类型名)(表达式) :会导致数据精度的损失
四、表达式:由常量、变量、函数和运算符组合起来的式子
1、赋值运算符:“=”,具有右结合性
2、复合 赋值运算符:“+=”、“-=”、“*=”、“\=”
3、算术运算符:+、-、*、/、% (注意:/操作数若均为整型,则结果也为整型,若其中有一个为实型,则结果为双精度实型;%的操作数必须都为整型,结果取整)
4、自增、自减 :++i、i++、--i、--i(++在变量之后,先赋值再运算;++在变量之前,先运算再赋值)
5、关系运算符:<、<= 、>、>=、==、!=
优先级(算术运算符>关系运算符>赋值运算符)
五、算法、语句结构和条件语句
1、算法:解决问题所使用的一系列合乎逻辑的、简洁的步骤
程序 = 数据结构 + 算法 + 程序设计方法 + 语言和环境
2、算法特性:有穷性、确定性、有效性、有0个或多个输入、有1个或多个输出
3、 c++语句分类:(1)表达式语句、(2)空语句、(3)程序控制语句 、(4)复合语句,可以嵌套
4 、if语句:
(1)第一种形式:
if(表达式){
语句;
}
(2)第二种形式:
if(表达式){
语句;
}
else(表达式){
语句;
}
(3)第三种形式:
if(表达式){
语句;
}
else if(表达式){
语句;
}
else(表达式){
语句;
}
注意:(1)if-else匹配原则:就近原则(else与最近的if进行匹配)
(2)当布尔表达式与一个常量值进行比较时,一般把常值放在前面
(3)不可将布尔变量直接与true、false、0、1进行比较
5、switch语句
形式:
switch(表达式)
{
case 常量表达式1:
语句1
break;
case 常量表达式2:
语句2
break;
……
case 常量表达式n:
语句n
break;
default:
语句n+1
}
注意:这里的break可写可不写。当表达式与常量表达式匹配后,执行当前的case中的语句,若不写break,则继续往下执行 case中的语句,此时不管表达式和常量表达式是否匹配,都继续执行后续case中的语句
例子:
#include
using namespace std;
int main(){
int a = 0 ,b = 1;
switch(b)
{
case 0:
a++;
case 1:
a++;
case 2:
a++;
}
cout << "a="<
输出结果a=2,这里b匹配到case 1之后,执行a++,由于没有break语句,无法跳出循环,所以会继续往下执行case 2中的a++
6、循环语句
(1)goto语句:可以跳转到指定标识符的地方
#include
using namespace std;
int main()
{
int i = 0,sum = 0;
loop:if(i <= 100){
sum += i;
i++;
goto loop;
}
cout<
(2)while循环
形式:
while(表达式){
循环体
}
例子:
#include
using namespace std;
int main()
{
int i = 0,sum = 0;
while(i<=100){
if(i % 2 == 0){
sum += i;
}
i++;
}
cout << sum << endl;
return 1;
}
(3)do-while循环
do{
循环体
}
while(表达式);
while循环可能一次都不执行循环体,而do-while循环至少执行一次
例子:
#include
using namespace std;
int main()
{
int i= 0 ,re = 0;
cin >> i;
do{
re = i % 10;
i = i / 10;
cout << re;
}
while(i);
return 1;
}
(4)for循环
形式:
for(循环变量初始值循环表达式;循环终止初始条件){
语句
}
例1:
#include
using namespace std;
int main()
{
int i= 1 ,sum = 0;
for(i;i<=100;i++){
sum += i;
}
cout << sum <
例2(输入10个字符,输出最大字符的ascii码):定义一个字符,然后将它赋值给一个整型变量,就可以得到这个字符的ascii码
#include
using namespace std;
int main()
{
int max1 = 0;
char c;
for(int i = 1;i<=10;i++){
cin >>c;
if(max1
注意:return语句可以不条件终止函数,一旦遇到return,其后所有的语句都不执行
多层循环:长循环包含在短循环里面
双重循环:(1)外层循环执行一次,内层循环执行一遍
(2)外层循环控制行,内层循环控制列
7、数组:数据类型相同,按一定的顺序排列的多个数的集合
c++中的结构数据类型可分为数组类型、结构体类型和共用体类型
1、一维数组
(1)形式:类型 数组名[常量表达式(一般指的是数组的长度,也就是可以在数组里存放的数据个数)],如int a[6];
注意:int n = 5; int a[n];这样的写法是错误的,数组的长度一定是一个常量表达式
(2)数组的引用:
①必须先定义数组,才能引用数组元素
②只能逐个引用数组元素,不能一次引用整个数组
③下标是该元素在数组中的位置标识,只能是整型常量或整型表达式
(3)一维数组初始化:
①在定义数组的时候,对数组中的部分元素或者所有元素赋值
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int a[10] = {1,2,3};
②对数组中的全部元素赋初始值时,可以不给出相应的数组长度
int a[]={1,2,3,4,5,6,7,8,9,10};
③特殊情况:
int a[10] = {5};
这种情况下,第一个数会被赋值为5,其他元素被赋值为0
注意:①数组不初始化,其元素为随机数
②对static数组元素不赋初值,系统会自动全部赋值该类型的零
(4)字符数组
形式:char 数组名字[长度]
赋值:char ca[5] = {'a','b','c','d','e'};、char cb[5]="acsf";
注意:使用字符数组存储一个字符串时,实际的存储长度为数组长度减1,因为字符串在存储的时候会在结尾处自动加上一个\0
关于字符数组的函数:
①获取字符数组长度:sizeof(字符数组名字):int na = sizeof(ca);
②获取字符串长度:strlen(字符数组名字):int nb = strlen(cb);
(5)结构体:可以存储各种类型的数据
形式:
struct 结构体名{
类型 成员变量;
类型 成员变量;
……
};
结构体的声明:
struct studentStruct{
int no;
char name[20];
char sex;
float score;
};
结构体变量:struct studentStruct student={101,"张三","M",93.5};
结构体变量的使用方法:
①先声明结构体类型,再定义变量
struct 结构体名{
类型 成员变量;
类型 成员变量;
……
};
struct 结构体名 变量名={变量名列表};
②声明结构体的同时定义变量
struct 结构体名{
类型 成员变量;
类型 成员变量;
……
}变量名 = {变量名列表};
③直接定义结构体类型变量
struct {
类型 成员变量;
类型 成员变量;
……
}变量名={变量名列表};
这种方法少了结构体名。
结构变量的获取:student.no
结构体类型和结构体变量的区别:
①声明结构体类型时系统不分配内存,而定义结构体变量时系统为其分配内存
②结构体类型不能进行赋值、存取、运算等,而结构体变量可以
结构体可以嵌套:
嵌套方法一:
struct student{
int no;
char name[20];
struct date{
int mouth;
int day;
int year;
}birthday;
}stu = {23,"张三",{12,31,2018}};
嵌套方法二:
struct date{
int mouth;
int day;
int year;
};
struct student{
int no;
char name[20];
struct date birthday;
}stu{101,"张三",{2,7,1995}};
引用规则:
①结构体变量只能引用成员变量,不能整体引用
②一般引用形式:结构体变量名.成员名
③结构体嵌套时逐级引用
(6)二维数组
形式:类型 数组名[常量名1][常量名2] ,如:int a[3][4]
①二维数组初始化
i)按行分段赋值:int a[2][3] = {{1,2,3},{4,5,6}};
ii)按行连续赋值:int a[2][3] = {1,2,3}
缺省部分将全部自动补0
#include
using namespace std;
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int b[3];
int max1 = 0;
for(int i = 0; i < 3; i++){
for(int j = 0;j < 3;j++){
if(a[i][j] > max1){
max1 = a[i][j];
}
}
b[i] = max1;
max1 = 0;
}
for(int i = 0;i <3 ;i++){
cout << b[i]<
8、函数
分类:库函数,自定义函数 / 有参函数、无参函数
(1)形式:
类型名 函数名(类型名 形参1,类型名 形参2……){
说明语句;
执行语句;
}
注意:①形参之间使用逗号进行间隔
②函数体为空的函数称为空函数
③函数的定义是平行的,不允许在一个函数的内部再定义一个函数
④使用return关键字返回值,返回值类型与函数类型相同或兼容;若不要求返回值,则函数类型为void;若省略函数类 型,则默认为int
(2)函数声明的三种形式:
——类型 函数名(类型 形参1,类型 形参2……); 如:int max(int a,int b)
——类型 函数名( ); 如:int max()
——类型 函数名(类型,类型……); 如:int max(int,int)
注意:当我们把自定义函数写在main函数下方时,在main函数中若要调用自定义函数,需要在main函数中先进行函数声明。被调函数若出现在主函数之前,则不需要进行函数声明。
例子:
#include
using namespace std;
int main()
{
void add(int x,int y);//首先进行函数声明
int a,b;
cin >> a >> b;
add(a,b);
return 0;
}
void add(int x,int y)
{
int sum = 0;
sum = x+y;
cout << sum << endl;
}
这里,在main函数中首先声明了void add(int x,int y);
(3)函数调用方式:
①函数语句:函数名(参数……);/函数名( );
②函数表达式:m = max(a,b)*2;
③函数实参:m = max(a,max(b,c));
注意:①无论一个函数是否有参数,在被调用时函数名后面都需要有括号。
②主调函数传递给被调函数的参数个数必须一致,类型必须兼容。
③一个函数只能有一个返回值。
例子:
#include
using namespace std;
int main()
{
int diff(int a,int b,int c);
int a,b,c;
int r;
cin >> a >> b >> c;
r = diff(a,b,c);
cout << "max-min = "<b?a:b);
z = (t>c?t:c);
return z;
}
int min3(int a,int b,int c){
int t,z;
t = (a
(4)函数递归调用
①概念:函数的递归调用是指一个函数在它的函数体内直接或间接的调用它自身。
②形式:
//直接调用
sum(){
……
sum();
……
}
//间接调用
sum1(){
……
sum2();
……
}
sum2(){
……
sum1();
……
}
例子:
#include
using namespace std;
int main()
{
long power(int n);
long f;
f = power(4);
cout << "4! = "< 1){
f = power(n - 1) * n;
}
else{
f = 1;
}
return f;
}
(5)文件包含
①形式:i)#include <文件名>:包含库文件一般使用这种形式
ii)#include "文件名":自己编制的函数一般使用这种形式,编译器从当前目录下查找包含文件,找不到则再到库文件所 在的目录查找。
注意:一个#include命令只能包含一个文件
②内部函数:
——在函数类型和函数名的前面加上关键字static,又称为静态文件。
——内部函数只能被本文件中其它函数所调用。
③外部函数:
——在函数类型和函数名的前面加上关键字exrern,若省略extern则隐含该函数为外部函数。
——外部函数可以被所有文件所调用。
④函数之间的调用方法
在一个项目中,可以有多个cpp文件,如现有两个cpp文件(main.cpp和test.cpp),我们需要在main.cpp中使用test.cpp中的函数。首先需要生成一个test对应的头文件(test.h),在这个头文件中,只需要写上test.cpp中所定义的函数的函数声明;然后在main.cpp文件中加上#include "test.h";最后在main.cpp中调用test.cpp中的函数即可。这样就完成了在main.cpp中调用别的文件中的函数。
(6)变量
①局部变量:在函数内或语句块内定义,只在本函数或本语句块内有效。不同函数或语句块可以定义同名的局部变量,分配不同的存储单元,它们之间互不干扰,不会混淆。
例子:
using namespace std;
int main()
{
int x = 1,y = 2;
int sum;
sum = x + y;
{
int sum = 8;
cout << "内层sum为" << sum << endl;
}
cout << "外层sum为" << sum << endl;
}
②全局变量:在所有函数外部定义的变量,有效范围从定义位置到本文件结束。
注意:i)当全局变量与局部变量同名时,则全局变量会被屏蔽
ii)应该避免不必要地使用全局变量,原因:a.全局变量在程序执行期间都占用内存,如果定义很多的全局变量,则系统运 行中需要消耗很多的内存 b.会降低函数的通用性、可靠性、可移植性;降低程序清晰度,易出错
③变量存储方式:i)全局变量和静态局部变量会分配固定的存储空间
ii)形参、函数调用时传过来的参数、非静态局部变量会动态的分配存储空间
④变量的存储类别:自动的(auto)、静态的(static)、寄存器(register)、外部的(extern)
变量定义:[存储类别] 数据类型 变量名;
i)auto变量:动态存储方式,省略存储类别时,默认为auto类别,如果不赋初值,则其值是一个不确定的值
ii)static变量:随着程序的产生而产生,一旦其值发生改变,它就不会变为初始值。在程序运行期间始终不释放它的内存单元。
注意:static变量具有可继承性,在整个程序运行期间只赋一次初值,若没有赋初值,则默认为0。以后调用不再重新赋初 值,而只是保留上次调用后的值。
例子:
#include
using namespace std;
int main(){
void add();
for(int i = 0;i < 3;i++){
add();
}
}
void add(){
static int x = 0;
int y = 1;
int z = 0;
x++;
y++;
z = x + y;
cout << "x = " << x << ",y = " << y << ",z = " << z << endl;
}
输出结果:
iii)register变量:只有非静态局部变量和形参可定义为register
一个系统中的寄存器是有限的,我们不能频繁的去定义register变量,现有编译器会自动将频繁使用的变量放在寄存器中以提高小效率。
iv)extern变量:在命令空间中声明的变量,默认情况下都是外部变量。外部变量是能够在多个原文件中共享的全局变量。在一个源文件中定义的外部变量,要在另一个文件中使用时,要用extern关键字修饰。
局部变量 | 全局变量 | ||||
存储类别 | auto | register | static | extern | static |
存储方式 | 动态存储方式 | 静态存储方式 | |||
存储区 | 动态存储区 | 寄存器 | 静态存储区 | ||
作用域 | 函数/语句块内 | 定义及声明的文件内 | 本文件内 | ||
生存期 | 函数/语句块调用期间 | 整个程序运行期间 | |||
赋初值 | 每次调用时重新赋初值 | 只赋一次初值 |
⑤变量访问形式
i)直接访问:按变量地址存取变量值(int i = 3,i有一个存放地址,访问变量i时,直接根据i的地址读取i的值)
ii)间接访问:通过存放地址的变量去访问变量(这里用到的就是指针的概念。一个指针变量中存放的是一个地址信息,通过这个地址信息我们去找变量的值)(i_pointer = 2000; *i_pointer = 20; 通过这种方式,就会将存储地址为2000的值赋值为20。)
⑥指针变量
i)一般形式:[存储类型] 数据类型 *指针变量名(如:int *p;)
ii)注意:a.int *p1,*p2; 与 int *p1,p2的区别;
b.指针变量名是p1、p2,不是*p1、*p2;
c.指针变量一般只能指向定义时所规定的同一类型的变量;
d.通用指针:void *指针名;
e.指针变量只能存放地址。
定义指针变量,在使用的时候需要先给这个变量赋一个地址值。
iii)两个指针运算符:a.取地址运算符:&
b.间接访问运算符:*
iv)零指针/空指针:int *p = 0; 或 int *p = NULL; 表示指针变量的值为0。这两种方式都表示p指向地址为0的单元,系统保证该单元不作他用,表示指针变量值没有意义。
例1:
#include
using namespace std;
int main(){
int a,b;
int *i_a,*i_b;
a = 30;
b = 40;
i_a = &a;
i_b = &b;
//输出a和b的值
cout << a <<"," << b << endl;
cout << *i_a << "," << *i_b << endl;
//输出a和b的地址
cout << &a << "," << &b << endl;
cout << i_a << "," << i_b << endl;
//通过指针改变a和b的值
*i_a = 0;
*i_b = 0;
cout << a <<"," << b << endl;
cout << *i_a << "," << *i_b << endl;
return 0;
}
输出结果:
例2:
#include
using namespace std;
int main(){
int a = 0;
int b = 0;
int *i_a,*i_b;
a = 50;
b = 100;
i_a = &a;
i_b = &b;
//输出a和b的值
cout << a <<"," << b << endl;//50,100
cout << *i_a << "," << *i_b << endl;//50,100
i_b = &*i_a;
cout << *i_a << "," << *i_b << endl;//50,50
cout << *&a << "," << a << endl;//50,50
cout << &i_a << "," << &i_b << endl;
cout << &*i_a << "," << &*i_b << endl;
cout << &a << "," << &b << endl;
(*i_a)++;
cout << *i_a << endl;//51
return 0;
}
输出结果:
例3:(利用指针比较两个数的大小)
#include
using namespace std;
int main(){
int a,b;
int *p_a,*p_b;
cin >> a >> b;
p_a = &a;
p_b = &b;
if(*p_a < *p_b){
p_a = &b;
p_b = &a;
}
cout << *p_a << ">=" << *p_b << endl;
cout << a << "," << b << endl;
return 0;
}
在这里,if语句中并没有改变a,b的值,如果将if语句块改成如下形式:
int temp;
if(*p_a < *p_b){
temp = *p_a;
*p_a = *p_b;
*p_b = temp;
}
如果发生交换,a,b的值也会发生交换。
v)指针变量作为函数参数传入时,按地址传递。在函数定义时,可以把*pointer_name看做一个整体,当做一个相应类型的变量,在使用时和普通变量的使用方法一样。但在调用这个函数时,实参需要传入的是指针变量的地址。
#include
using namespace std;
void swap1(int *a,int *b)
{
int temp;
if(*a < *b){
temp = *a;
*a = *b;
*b = temp;
}
}
int main(){
int a,b;
int *p_a,*p_b;
cin >> a >> b;
p_a = &a;
p_b = &b;
swap1(p_a,p_b);
cout << *p_a << ">=" << *p_b << endl;
cout << a << "," << b << endl;
return 0;
}
vi)指针与数组
指向数组元素的指针变量,与指向普通变量的用法一样。指针变量指向的是数组中的某一个元素。
例子:
int a[10];
int *p;
p = &a[0];//等价于p = a;
注意:a.p = &a[0];等价于p = a;(数组名等价于第一个数组元素的地址)
b.a[i] = *(p+i)
例:
#include
using namespace std;
int main(){
int a[5];
int i;
for(i= 0;i < 5;i++){
a[i] = i;
}
int *pa;
pa = a;
for(int i = 0;i<5;i++)
cout << a[i] << "," << endl;
for(int i = 0;i<5;i++)
cout << pa[i] << "," << endl;
for(int i = 0;i<5;i++)
cout << *(pa+i) << "," << endl;
for(int i = 0;i<5;i++)
cout << *(a+i) << "," << endl;
return 0;
}
对于数组指针p,p[i]和*(p+i)只是同一个元素的不同表示方法。
vii)指针函数
格式:类型名 *函数名(参数类型)(如:int *lookfor(int n);)
(7)面向对象基本概念与类
①对象:对象由对象名、属性、函数构成
抽象是指对每一类对象进行概括,抽出这类对象的公共性质并用计算机语言加以描述的过程。
把具有相同属性和相同操作的一些对象抽象为一个类。这些对象都是这个类的实例
②封装(private):通过封装,将一部分的属性和操作隐藏起来,不让使用者访问,另一部分作为类的外部接口,使用者可以访问。
封装的定义:i)一个清楚的边界。对象的所有属性和操作都被限定在这个边界内
ii)一个外部接口。该接口用以这个对象和其它对象之间的相互作用,就是用户可以直接使用的属性和操作
iii)隐藏受保护的属性数据和内部操作。封装起来的属性或操作,只能在本类中去使用。
对象的结构由类描述,每个类的属性和操作都可以分为私有的(private)和公有(public)的两种类型。
③继承:一层一层不断深入的过程
④多态:相同的函数名可以有若干个不同的函数体,在调用同一函数时由于环境不同,可能引起不同的行为,这种功能称为多态。函数名重载是实现多态的一种手段。如两个同名的Max函数:
int Max(int x,int y);
int Max(int x,int y,int z);
(8)类(class)
类也是一种数据类型,可以声明类的变量,由类生成的变量不再称为变量,而称为对象。
格式:
class 类名{
private:
私有的数据和函数
protected:
保护的数据和函数
public:
公有的数据和函数
};
如:
class Rect{
private:
float x,y;
public:
void set(float a,float b);
float peri();
float area();
};
在类中,数据称为数据成员,函数称为成员函数
(9)成员函数:成员函数实现对类中数据成员的操作,它描述了类的行为。由于对象的封装性,类的成员函数是对类的私有数据成员进行操作的唯一途径。
成员函数的实现:成员函数在类中声明后,需要进一步定义这个成员函数,来实现它的操作功能。
成员函数定义的结构:
类型 类名 :: 成员函数名(参数列表){
成员函数体
}
例:
class Date{
private:
int Year,Mouth,Day;
public:
Date(int ye,int mo,int da);//构造函数
void Set(int y,int m,int d);
void Display();
};
void Date::Set(int y,int m,int d){
Year = y;
Mouth = m;
Day = d;
}
void Date::Display(){
cout << "日期为:" <
成员函数的定义的结构与普通函数不同的地方是:在类型和成员函数名之间加了一个类名和双冒号“::”。“::”是作用域运算符,用来标识成员函数或数据属于哪一个类。
成员函数的存取权限有三级:
①公有的public:它定义了类的外部接口,可以被用户程序直接访问
②私有的private:它定义了类的内部使用的数据和函数,私有成员只能被自己所属类的成员函数访问,用户程序不能直接访问
③保护的protected:存取权限介于公有成员和私有成员之间,它在类的继承中使用
(10)对象:类是描述一类问题的公共属性和行为,对象是类的实例,对象是由类作为类型定义的变量。
格式:类名 对象名
访问对象中的公有成员的语法格式:对象名.公有数据成员;、对象名.公有成员函数名(参数列表);
类的实例化(也就是对象)是创建在main函数当中的
(11)构造函数
构造函数在对象被创建的时候由系统自动调用。它也是类的一个成员函数。
构造函数的名字与类名相同,而且不能有任何的返回类型,也不能标为void类型。
构造函数一般被声明为公有函数,构造函数也可以重载(重载是指函数名相同,但参数不同)
如:
class Date{
private:
int Year,Mouth,Day;
public:
Date(int ye,int mo,int da);//构造函数
void Set(int y,int m,int d);
void Display();
};
实现构造函数:
Date::Date(int ye,int mo,int da){
Year = ye;
Mouth = mo;
Day = da;
}
调用(使用构造函数来传参,直接在对象声明的时候就可以对其赋值):
Date brithday(1995,02,07);
例:
#include
using namespace std;
class Date{
private:
int Year,Mouth,Day;
public:
Date();
Date(int ye,int mo,int da);//构造函数
void Set(int y,int m,int d);
void Display();
};
Date::Date(int ye,int mo,int da){
Year = ye;
Mouth = mo;
Day = da;
}
void Date::Set(int y,int m,int d){
Year = y;
Mouth = m;
Day = d;
}
void Date::Display(){
cout << "日期为:" <
构造函数的特点:
1)构造函数是特殊的成员函数,该函数的名称与类的名称相同,该函数不能指定返回类型;
2)构造函数可以重载,即可以定义多个参数个数不同或参数类型不同的构造函数;
3)构造函数在对象定义的时候直接使用,不能在程序中直接调用
4)默认情况下系统会分配一个无参的构造函数
5)自定义的有参构造函数会把无参构造函数覆盖掉,所有在定义了有参的构造函数后最好把无参构造函数写出来
(12)继承(基类和派生类)
①继承:在已有类的基础上定义新的类,而不需要把已有类的内容重写一遍。
已有类称为基类或父类,在此基础上建立的新类称为派生类或导出类、子类。
继承允许一个类从其它类中继承属性。如果一个对象从单个基类中继承了属性,就被称为单继承;如果一个对象从多个基类中继承了属性,就被称为多重继承。
从基类可以派生出多个类,这些派生类不仅有基类的特征,还可以定义自己独有的特征。
格式:
class 子类名:继承方式 父类名{
新增私有成员声明语句列表
public:
新增公有成员声明语句列表
protected:
新增保护成员声明语句列表
}
注意:继承方式决定了子类对父类的访问权限,有3种继承方式:private、public和protected,缺省时默认是private,最常用的是public。
例:
#include
using namespace std;
class point{
float x,y;
public:
point(float a=0,float b=0){x = a;y = b;}
void SetP(float a=0,float b=0){x = a;y = b;}
void Display(){cout << "位置是:("<
成员函数可以在类定义的时候直接完成函数体的书写。
子类对父类的访问是有限制的。
②单继承:每个派生类只有一个基类,派生类只从单个基类中继承属性。
多继承:由多个基类派生出新的类。
③类中成员的不用访问权限:
1)公有成员:一个类的公有成员允许本类的成员函数、本类的对象、公有派生类的成员函数、公有派生类的对象访问
2)私有成员:一个类的私有成员只允许本类的成员函数访问。
3)保护成员:具有私有成员和公有成员的特性。对其派生类而言是公有成员,对其对象而言是私有成员。