Chapter 8
指针、引用
指针—— 存储内存地址
变量 ——占用空间、声明、初始化(否则值为随机)
8.1 运算符
1.1 使用引用运算符(&)获取变量地址
e.g. Varname —— 变量
&Varname —— 存储该变量内存地址
1.2 使用接触引用运算符(*)
以此访问包含地址的值
e.g. 有合法指针——pData
那么该指针地址处存储的值可用 *pData 来获取
1.3 sizeof()
用于指针时,结果取决于编译器及针对的操作系统,与指针变量无关。
8.2 动态内存分配
1. 关键字new & delete 动态分配和释放内存
new分配新的内存块,若成功,返回一个指针,指向新分配的内存,否则引发异常(使用时,指定数据类型分配内存)
Type* Pointer = new Type;
Type* Pointer = new Type[ Num Elements ];
e.g.
int * pNumber = new int;
int * pNumber = new int[ 10 ];
注 :请求分配内存并不保证请求能够得到满足,取决于系统状态机内存资源的可用性。
使用关键字 new 分配的内存最终使用对应的关键字 delete 释放
Type* Pointer = new Type;
delete Pointer;
或
Type* Pointer = new Type[ Num Elements ];
delete [] Pointer;
2. 递增(++)、递减(--)运算符作用于指针的结果
对指针执行递增 / 递减, 指向的是内存中相邻的值,而不是相邻的字节(除非值的长度刚好1字节,例如char)
Type * pType = Address;
++pType --> Adress + sizeof( Type )
3. 关键字const作用于指针
const指针有三种:
a )指针直线的数据为常量,不可修改,但可以修改包含的地址(指针可指向其他地址)
b ) 指针包含地址为常量,不能修改,可以修改数据
c ) 最为严格的情况,地址及值均为常量,均不可修改,但更易于维护。
4. 将指针传递给函数
将内存空间传递给函数,其中可包含值,可包含结果
注意传入的数据是否需要修改或者经过计算。
5. 数组与指针
可以将数组变量赋值给类型相同的指针。
8.3 常见错误
1.内存泄露
常见原因是未正确释放内存
2.指向无效的内存单元
无效指针
3.悬浮指针
亦可称之为迷途/失控指针
为便面此类问题,初始化/释放指针后将其置为NULL,并在解除引用前(使用关键字 ** * **)检查其是否有效。
8.4 编程实践
Step1 初始化指针变量
step2 使用前判断指针是否为NULL——>异常处理,在new(创建指针)失败时妥善退出
Step3 仅在其有效时使用
Step4 new之后必用关键字delete释放内存,且delete后不再访问该指针
8.5 引用(&)
引用是变量的别名(相应变量的的另一个名字,指向相同的内存单元)
VarType Original = Value;
VarType & ReferenceVariable = Original;
1.引用的用处
避免了传参时因参数占用内存过大,复制时也会开销很大。
2. const 用于引用
禁止通过引用修改其指向的变量的值。
const引用参数不能作用于左值
3. 按引用向函数传递参数
可避免将形参复制给形参,从而极大提高性能。然而,让被调用的函数直接使用调用函数栈时,确保被调用函数不能修改调用函数中的变量很重要。因此,可将引用声明为const
Chapter 9 类和对象
9.1 类和对象简述
1. 类的声明
关键字 class 依次包含类名、成员属性、方法(属于类成员的函数)及结尾分号(;)
即通过关键字class创建数据类型,并封装属性。
"封装" 将数据及使用它们的方法进行逻辑编组
2.实例化对象
在使用时,根据类实例化一个对象,通过对象访问成员方法及属性。
class Human
{
string Name;
string DateofBirth;
void Talk( string TexttoTalk );
};
那么实例化一个对象Tom
//方法一
Human Tom;
//方法二
Human* pAnotherHuman = new Human( );
delete pAnotherHuman;
3.通过句点运算符(.)访问成员
句点运算符(.)用于访问对象的属性。这同样适用于方法。
Human Tom;
Tom. DateofBirth = "1970" ;
Huamn* pTom = new Human();
(*pTom).IntroduceSelf();//使用间接运算符(*)获取对象,再使用句点运算符来访问成员。
4. 使用指针运算符访问成员(->)
若对象使用new实例化或有指向对象的指针,则可以使用 **指针运算符(->)**来访问成员属性和方法。
Chapter 11
**
11.1. 多态基础
1.1
类之间存在层次结构,类是通过继承相关联时,通过多态来表示。
多态意味着调用成员函数时,根据函数的对象类型执行不同的方法。(而不是调用预设的基类中的函数方法),即表现实际类型。
1.2
使用虚函数实现多态行为
将基类中方法声明为虚函数,使用关键字 virtual, 确保编译器调用覆盖版本(子类、派生类)。
多态行为 将派生类对象视为几类对象,并执行派生类的函数(方法)实现。
1.3 为何需要虚构造函数
除了需要使用派生类对象,还需要避免计算机资源未释放、内存泄露等问题(即将实例化的派生类对象,将其值赋给基类当做指针,并通过该指针调用 delete, 将不会调用派生类的析构函数)
**⬇**
那么将析构函数声明为虚函数,确保通过基类指针调用delete时,不会调用派生类析构函数
class Base
{
public:
virtual ~Base()
};
auto 关键字
利用auto关键字,通过编译器检查变量的初始值,并将该变量类型设置为该返回值的类型。能够简化编码工作。
std::vector<int> MyNumbers;
//常规
for (vector<int>::const_iterator Iterator = MyNumbers.begin();
Iterator < MyNumbers.end(); ++Iterator )
std::cout << * Iterator<< " ";
//利用auto关键字
for (auto Iterator = MyNumbers.begin();
Iterator < MyNumbers.end(); ++Iterator )
std::cout << * Iterator<< " ";
**
支付宝
微信