1. const形参
如果使用形参的唯一目的是避免复制实参,则应该将形参定义为const,即应该将不需要修改的引用参数定义为const引用。普通的非const引用形参在使用时不太灵活。这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。
2. 关于形参
函数的参数传递包含以下几种:
2.1 非引用形参 int func(int v1); int func(int *p)
2.2 引用形参 void swap(int &v1, int &v2)
2.3 传递指向指针的引用 void ptrswap(int *&v1, int *&v2),其中int *&v1应该从右向左理解:v1是一个引用,与指向int型对象的指针相关联。
2.4 假如是数组形参,通常将数组形参直接定义为指针要比使用数组语法定义更好。这样就明确表示,函数操纵的是指向数组元素的指针,而不是数组本身。由于忽略了数组长度,形参定义中如果包含数组长度则特别容易引起误解。另外当编译器检查数组形参时,它只会检查实参是不是指针、指针的类型是不是和数组元素匹配,而不会检查数组的长度。
3. 关于return
返回值谨记两点:千万不要返回局部对象的引用,千万不要返回指向局部对象的指针。
4. 关于内联函数
调用函数比求解表达式要慢得多,因为涉及到保存寄存器等工作。内联函数优点是可以避免函数调用的开销。即在编译时就将展开为内联函数的语句,从而消除了调用函数的额外开销。
内联函数应该在头文件中定义,这一点不同于其他函数。
类的成员函数可以在类内定义,也可以在类外定义,编译器隐式地将类内定义的成员函数当作内联函数。
5. 关于const成员函数
5.1 成员函数声明为const, 表明它们不修改类对象。
5.2 只有被声明为const 的成员函数才能被一个const 类对象调用。关键字const 被放在成员函数的参数表和函数体之间。对于在类体之外定义的const 成员函数,我们必须在它的定义和声明中同时指定关键字const。
5.3 把一个成员函数声明为const 并不能阻止程序员可能做到的所有修改动作。把一个修改类数据成员的函数声明为const 是非法的。但是,如果该类含有指针,那么在const 成员函数中就能修改指针所指的对象。
5.4 const 成员函数可以被相同参数表的非const 成员函数重载。
6. 使用下标访问map对象
map<string, int> word_count;
word_count["Anna"] = 1;
将发生以下事情:
(1)查找word_count中键为Anna的元素,没有找到;
(2)将一个新的键-值插入到word_count中,它的键是const string类型的对象,保存Anna。而它的值则采用值初始化,这意味着在本例中值为0;
(3)将这个新的键-值插入到word_count中;
(4)读取新插图的元素,并将它的值赋为1。
注:使用下标访问map与使用下标访问数组或者vector的行为截然不同,用下标访问不存在的元素将导致在map容器中添加一个新元素,它的键值即为下标值。但是如果该键值已经在容器中,则map的下标运算与vector的下标运算行为相同。可以比较如下例子:
map<int, int> m; m[0] = 1;
vector<int> v; v[0] = 1;
7. 关于静态数据成员
7.1 不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。
static成员变量不属于对象的一部分,而是类的一部分,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量。但是首先你必须初始化它。 初始化static成员变量不能安排在类的构造函数中,因为构造函数可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化安排在头文件中,因为它可能会被包含在许多地方。而应该放在main函数之中,或全域函数中,或者任何函数之外。
7.2 静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。举例如下:
class base{
public :
static int _staticVar;
int _var;
void foo1(int i=_staticVar);//正确,_staticVar为静态数据成员
void foo2(int i=_var);//错误,_var为普通数据成员
};
7.3 静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用。举例如下:
class base{
public :
static base _object1;//正确,静态数据成员
base _object2;//错误
base *pObject;//正确,指针
base &mObject;//正确,引用
};
7.4
静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。
7.5 静态成员函数不可以同时声明为 virtual、const、volatile函数。