函数
cpp对函数之间的的排列要满足先定义后使用。后定义先调用的函数必须声明。因为在函数被调用之前,应当让编译器知道该函数的原型。
内存区域
- 代码区
- 存放程序的可执行代码
- 全局数据区
- 静态变量
- 一般的全局变量(自动初始化为0)
- 栈区
- 局部变量(不处理原内存中的值)
- 堆区
- 与指针有关的动态数据
变量
全局变量若和局部变量同名,需要加上::
static
static修饰的变量为静态变量、内部变量。其中局部静态变量具有局部作用域,但是却具有全局生存期。
static变量作为类的静态变量时,需要在类外部(.cpp)进行定义,如
float Stub::staticVariable=0;
静态函数成员的调用
Stub::stubmethod();
extern作用域从定义处到当前文件结束
默认参数
1 | void showArea(int a = 0,int b = 10) |
模板
函数模板
1 | template <class T> |
类模板
编译器看到类模板时并不为它分配内存空间,直到定义了一个模板对象,即模板参数由编译器替换时,才为其分配空间。
1 | template < class T > |
内联函数
一定要放在头文件中
方法是加上inline关键字
编译器在编译时,会将内联函数采用函数体进行替换,是以增加目标代码为代价来换取时间的。
指针
1 | //返回指针 |
void指针表示任何类型。但是不能对其使用算数操作。
const可以修饰类型、变量名
- 修饰类型表示不可以通过指针改变现在所指的内容
- 修饰变量名,表示可以改变指针所指向空间的内容
Main
1 | int main(int argc , char *argv[]){ |
内存的动态分配和释放
new和delete
1 | int *iptr = new int; |
malloc和free
1 | NODE * NODE; |
结构体
1 | typedef char NAME[100]; |
类
1 | class Stub{ |
.h文件和.cpp文件
将类的定义存储在头文件中,函数成员放在cpp文件中
1 | //Rectangle.h |
友元函数
友元函数不是类中的函数成员,但它可以访问类中定义的私有成员。
友元破坏了数据的封装和隐藏,尽量不使用或少适用友元。
外部函数作为类的友元
1 | //类中定义 |
类的成员函数作为另一个类的友元
这样的成员函数也被称为友元成员。既可以访问所在类对象的私有成员,也可以访问friend声明语句所在类对象中的私有成员和公有成员。
1 | class Budget{ |
一个类作为另外一个类的友元
B类中的每个函数成员都能访问A类中的私有成员。
1 | class A{ |
拷贝构造函数
并不调用构造函数,而是采用对象按位拷贝操作,将b对象的每个成员复制到a中。这样如果b中有指针,a中也会有指针,而a对象在析构的时候可能会删除指针指向的内容,导致b对象错乱。
1 | Stub a = b; |
拷贝构造函数是特殊的构造函数,当采用一个对象初始化另一个对象时,将自动调用该函数。
拷贝构造函数在对象被创建时调用,而赋值函数在对象已经存在的情况下调用。
1 | class Stub{ |
操作符重载
1 | class Stub{ |
技巧
创建一个临时对象将其返回 和 创建一个局部变量并返回 是不同的。
场景1:
- 创建一个temp对象,调用构造函数完成初始化;
- 拷贝构造函数将temp赋值到内存的外部存储中;
- 在函数结束时,摧毁temp对象
而场景2:直接把临时对象创建并初始化在内存的外部存储单元中,省去了调用拷贝构造函数和析构函数的过程,提高了效率。
1 | // 1 |
继承
CPP可以多重继承,其中子类的同名函数需要作用域分隔符::来确定要调用的函数
1 | class Son : public Father { |
异常
1 | float divide(int dividend , int divisor){ |
初始化列表
构造函数参数表和函数体之间,在构造函数的函数体执行之前完成初始化列表中指定的工作。
- 具有继承关系的子类必须在初始化列表中调用基类的构造函数
- 类中的const常量成员只能在初始化列表中进行初始化
- 对象类型的成员的初始化放在初始化列表中则程序的效率较高
Virtual
CPP编译器在默认情况下,对函数成员的调用实施的是静态绑定。如需改为动态绑定,需要增加前缀virtual
虚函数是一个函数成员,唯一要求是在子类中一定要覆盖它。
纯虚函数
virtual <> <>() = 0;
其他
CPP中字符串末尾要有\0