命名空间+缺省参数+const总结+引用总结+内联函数+auto关键字 C++初阶( 六 )

注意事项:

  • 常成员函数的定义和声明都要含有const关键字
  • 一个函数是否含有const关键字可以作为重载函数,const对象默认调用const函数,非const对象默认调用非const函数,如果没有非const函数,也可以调用const函数
  • const函数中不能更新目的对象的任何成员(mutable修饰的变量除外,这里不展开阐述),以此方法来保证const对象不被修改
  • 如果const成员函数想修改成员变量值,可以用mutable修饰目标成员变量
类的常数据成员类的数据成员不能在任何函数中被赋值或修改,但必须在构造函数中使用初始化列表的方式赋初值,因为const修饰的对象必须初始化 。举个例子,刚才的类如果a, b为常数据成员,则应该改写为如下形式:
class Example{public:    Example(int x, int y):a(x),b(y){} //初始化列表方式赋初值    void print();    void print() const;private:    const int a,b;};void Example::print() {cout<<"print():"<<a<<ends<<b<<endl;}void Example::print() const {cout<<"print() const:"<<a<<ends<<b<<endl;}如果为静态常数据成员,由于不属于具体对象,所以不能在构造函数里赋值,仍然应该在类外赋值 。特别地,如果静态常量为整数或枚举类型,C++允许在类内定义时指定常量值 。比如以下两种方式均合法:
class Example{public:    Example(int x, int y):a(x),b(y){}    void print();    void print() const;private:    const int a,b;    static const int c = 10; //静态常量};class Example{public:    Example(int x, int y):a(x),b(y){}    void print();    void print() const;private:    const int a,b;    static const int c; //静态常量};const int Example::c = 10;const修饰类对象用const修饰的类对象,该对象内的任何成员变量都不能被修改 。因此不能调用该对象的任何非const成员函数,因为对非const成员函数的调用会有修改成员变量的企图 。
class A{ public:    void funcA() {}    void funcB() const {}};int main{    const A a;    a.funcB();    // 可以    a.funcA();    // 错误    const A* b = new A();    b->funcB();    // 可以    b->funcA();    // 错误}const与宏定义的区别(1) 编译器处理方式不同define宏是在预处理阶段展开 。const常量是编译运行阶段使用 。
(2) 类型和安全检查不同define宏没有类型,不做任何类型检查,仅仅是展开 。const常量有具体的类型,在编译阶段会执行类型检查 。
(3) 存储方式不同define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存 。const常量会在内存中分配(可以是堆中也可以是栈中) 。
(4)作用范围不同
const有作用域,而define不重视作用域,默认定义处到文件结束,如果定义在指定作用域下有效的常量,那么define不能用 。
(5)const 可以节省空间,避免不必要的内存分配 。例如:

经验总结扩展阅读