第一章:面向对象方法概述
- 面向过程程序设计的主要特征是什么:程序由过程定义和过程调用组成。
- 面向过程程序设计方法的局限性至少有哪几个方面:开发软件的生产效率低下,难以应付日益庞大的信息量和多样的信息类型,面向过程程序设计方法难以适应各种新环境。
- 什么是面向对象程序设计
- 现实世界中的对象有哪些特征
- 什么是对象,什么是类?对象与类的关系是什么
- 什么是消息
- 什么是方法?在C++中它是通过什么来实现的?
- 什么是抽象和封装
- 什么是继承性?继承关系之间具有哪些特征
- 什么是多态性
- 面向对象程序设计的有点主要有哪些
第二章 C++的初步认识
-
C++的特点
- C++时C的超集
- C++是更好的C语言,保持了C语言简洁、高效、接近汇编的特点,并对C语言的功能做了扩充
- C++编写的程序质量更高
- 增加了面向对象的机制
-
C++程序的结构特点
- 类的声明部分
- 类的使用部分
-
const
修饰符:用来定义常量,与C语言中的define作用相似,但是const
有数据类型的概念,占用存储单元,有地址,可以使用指针指向它,通过const
关键词修饰的变量在程序的任何地方都不能更改它。 -
常指针:
char* const s="abc"
,这个形式表明这个指针指向的地址是常量,不能修改,但是指针指向的地址块的数据可以修改即:s[0]="1"
合法,s="123"
非法 -
非常指针:
const char* s="abc"
,这个形式说明指针指向的这个地址块的值为常量,地址块内的值不能修改,但是可以修改指针的指向即:s[0]="1"
非法,s="123"
合法 -
函数原型:
- 形式:返回值类型 函数名(参数列表),即
int add(int a,int b)
; - 函数原型(函数声明):参数列表可以不表达参数的名称,只需要标识参数的类型即可
- 函数的定义:函数的定义有函数的声明和函数体组成;
- 函数原型没有表示返回类型,C++默认函数的返回值为int;
- 函数的定义如果没有返回值,则必须在函数原型中表示返回类型为void,这样函数体中就不需要return
- 形式:返回值类型 函数名(参数列表),即
-
带有默认参数的函数
- 函数声明时,设置默认值得参数的必须在没有默认值参数的最右边。
- 函数调用时,若某个参数省略,则后面的参数都应该省略使用默认值(如果不省略则可能按照位置参数的规则给形参赋值)。
-
函数的重载
- 函数名相同。
- 函数的参数列表长度不同或者参数得类型不同。
-
重载的坑点
- 函数返回值类型不在重载的判断范围之内。
- 函数的重载与带默认值的函数一起使用,有可能引起二义性
- 在函数调用时如果给出的实参和形参的类型不同,C++编译器会自动进行类型转换,成功继续执行失败终止运行。在调用时如果两个重载函数仅在参数类型上不同并且参数类型满足C++的类型自动转换条件时,这时候无法区分调用哪一个重载函数,因为重载函数在参数列表长度一致的情况下只能通过参数类型判断,然而C++在某些情况下又能自动进行类型转换这就导致唯一的区分条件也没有了。
-
运算符new 与 delete
-
使用new运算符可以为数组动态分配内存空间,这是需要在类型后面声明数组大小
int *p = new int[10];
-
new可以为简单类型变量分配内存的同时初始化
int *p; *p = new int(99)
-
使用new运算符分配内存空间的时候如果内存空间不足,则分配内存空间失败,这是的编译系统会返回空指针NULL,因此是否分配成功需要进行空指针的检查
int *p; p = new int(99); if(!p){ // 空指针检查 cout<<"内存分配失败"; }
-
使用new分配的内存空间不会自动释放,只能通过delete释放。
-
-
引用
-
引用就是给变量的别名,应用与变量指向同一块内存区域
-
引用的形式:类型 & 应用名 = 已定义的变量;
-
必须声明引用时同时初始化;
int main(){ int i = 10; int &j = i; // 声明引用并初始化 }
-
引用可以传递:
int a=1; int &a1=a; int &a2=a1;
-
引用声明初始化之后不可以重新赋值
-
不能建立引用的数组
-
不能建立引用的引用和不能建立指向引用的指针
int &&r=n; // 错误,不能建立引用的引用 int &*p=n; // 错误,不能建立指向引用的指针
-
指针和引用的区别
- 指针是一个实体,需要分配内存空间。引用只是变量的别名,
不需要分配内存空间。 - 引用在定义的时候必须进行初始化,并且不能够改变。指针在
定义的时候不一定要初始化,并且指向的空间可变。引用的初始
值不能为NULL。 - 有多级指针,但是没有多级引用,只能有一级引用。
- 指针和引用的自增运算结果不一样。指针自增运算是指向下一
个空间,引用自增运算是引用的变量值加1。 sizeof
引用得到的是所指向的变量(对象)的大小,而sizeof
指针得到的是指针本身的大小。- 引用访问一个变量是直接访问,而指针访问一个变量是间接访
问。 - 使用指针前最好做类型检查,防止野指针的出现;
- 作为参数时也不同,传指针的实质是传值,传递的值是指针的
地址;传引用的实质是传地址,传递的是变量的地址; - 引用底层是通过指针实现的。
- 指针是一个实体,需要分配内存空间。引用只是变量的别名,
第三章 类和对象
-
-
成员函数的定义
- 普通成员函数的定于
- 内联成员函数的定义和声明:分为隐式定义/声明和显式定义/声明。
-
对象的定义
-
对象成员的访问
-
通过对象名和点运算符访问成员
Date date; int year = date.year;
-
通过指针访问成员
Date *date = new Date(); int year = date->year;
-
通过对象的引用访问成员
Date date; Date &d = date; int year = d.year;
-
-
构造函数和析构函数
- 特殊的成员函数,有系统自动调用;
- 析构函数
- 析构函数的名称与类名一样,没有返回值,没有参数,而且不能进行重载,在析构函数的前面需要有
~
号。
- 析构函数的名称与类名一样,没有返回值,没有参数,而且不能进行重载,在析构函数的前面需要有
-
创建对象的两种形式:
- 类名 对象名[(实参表)]
- 类名 *指针变量名=new 类名[(实参表)]:通过new运算符创建的对象一般不使用对象名,而是通过指针访问,通过
->
运算符指向成员;p->year。
-
对象的赋值:使用赋值运算符
=
进行赋值- 使用赋值运算符赋值时两个对象的类型必须相同
- 赋值仅仅只是数据成员的赋值,成员函数占有同一个函数代码段。
- 当类中存在指针时,可能会产生错误。
-
对象的复制:
-
拷贝构造函数:在建立一个对象的时候,使用一个已存在的对象去初始化这个新的对象;
Point p2(p1);
-
拷贝函数的特点
- 只有一个参数,并且是同类对象的引用。
- 每个类都有一个拷贝函数。
- 拷贝函数也是一种构造函数,有构造函数的特征。
-
自定义拷贝函数
类名:类名(const 类名 &对象名){ 拷贝函数函数体 }
-
拷贝函数的两种使用形式
- 类名 对象2(对象1):拷贝构造函数。
- 类名 对象2 = 对象1:复制运算符实际也是调用的拷贝构造函数。(复制运算符在对象初始化的时候调用了拷贝函数,如果对象已经初始化则不会调用拷贝函数。)
-
拷贝构造函数的三种调用情况:
-
用类的一个对象初始化另一个对象时
Point p2(p1);
-
当函数的形参是类的对象
-
当返回值是对象时
-
-
第四章 类和对象的进一步讨论
-
对象数组
-
定义的格式:类名 数组名[数组的大小];
-
初始化
// 构造函数只有一个参数 exan obj[4] = {12,32,345,53}; // 构造函数有多个参数 exam obj[2] = { exam(1,2), exam(3,4) } // 支持默认参数
-
对象指针
- 声明对象指针:类名 对象指针名*;
- 对象指针访问对象数组:
-
-
函数传递对象
- 使用对象作为函数参数:
- 使用对象指针作为函数参数
- 使用对象引用作为函数参数
-
静态成员变量
- 静态成员的定义格式:static 数据类型 变量名称
- 静态变量的初始化:静态变量的初始化应该在类外面单独进行,而且应该在定义对象之前进行,一般在main函数之前,类声明之后的特殊地带进行初始化。
- 静态变量的初始化格式:数据类型 类名::静态数据成员名 = 初始值
- 静态变量的访问格式:类名::静态变量名,对象名.静态数据成员名,对象指针->静态变量名;