自己很少使用C++,本科阶段也是使用C和Java比较多,现在主流的C++版本为C++ 11,所以也会涉及一些C++ 11的新特性。

持续更新中。。。

Const

const修饰符可以把对象转变成常数对象,意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用!任何修改该变量的尝试都会导致编译错误。

模板Template

C++ Template主要有两种用法,函数模板和类模板。

函数模板

template <class 形参名,class 形参名, ... > 
返回类型 函数名(参数列表){函数体}

类模板

template <class 形参名,class 形参名, ... > 
class 类名{类的内容};

这里class可以换成typename,两者用法完全一样。

单冒号(:)

1. 单冒号出现在构造函数声明里

如果单冒号出现在构造函数声明里,那它的作用是类构造函数(Constructor)的初始化列表,各初始化变量之间以逗号(,)隔开。例如下面的例子:

Entry(K key, V value):key(key1),value(value1){}

这里就制定了key这个参数的初始化值是key1,value的初始化值是value1。

注意,初始化列表的作用相当于在构造函数内进行相应成员变量的赋值,但两者是有差别的。在初始化列表中是对变量进行初始化,而在构造函数内是进行赋值操作。 两者的差别在对于const类型数据的操作上表现得尤为明显。const类型的变量必须在定义时进行初始化,而不能对const型的变量进行赋值,因此const类型的成员变量只能(而且必须)在初始化列表中进行初始化。

2. 如果出现在类声明里

类名冒号后面的是用来定义类的继承。基本写法是,

class 派生类名 : 继承方式 基类名 {
    派生类的成员
};

继承方式:public、private和protected,默认处理是public。

双冒号(::)

双冒号在C++中主要用于作用域说明。

::的前面一般是类名称,后面一般是该类的成员名称,C++为例避免不同的类有名称相同的成员而采用作用域的方式进行区分。例如A,B表示两个类,在A,B中都有成员member。那么,

A::member就表示类A中的成员member

B::member就表示类B中的成员member

再比如声明了一个类A,类A里声明了一个成员函数void f(),但没有在类的声明里给出f的定义,那么在类外定义f时,就要写成void A::f(),表示这个f()函数是类A的成员函数。

同时::也可以作为全局作用域符号,当全局变量在局部函数中与其中某个变量重名,那么就可以用::来区分。

宏定义#ifndef #define #endif

这三个一般出现在头文件(xxx.h)中,主要作用是避免同一个头文件被多个c文件引用,而造成的声明冲突。

在C语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用#ifndef宏定义,多个c文件包含同一个h文件也不会报错。

但是在c++语言中,#ifdef的作用域只是在单个文件中。所以如果h文件里定义了全局变量,即使采用#ifdef宏定义,多个c文件包含同一个h文件还是会出现全局变量重定义的错误。

所以一般写C++头文件的时候,都会采用这种组合写法。

#ifndef <标识> 
#define <标识> 
...... 
#endif 

标识可以自由命名,但每个头文件的这个标识都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef _STDIO_H_ 
#define _STDIO_H_ 
...... 
#endif