条款03:尽可能使用const

记住从右往左读,左边的修饰右边的。

char greeting[] = "Hello";
const char* p = greeting;//non-const pointer,const data
char* const p = greeting;//const pointer,non-const data

在*之前表示const修饰数据,是底层const,数据不可以修改;

在*之后表示const修饰这个指针,是顶层const,指针的指向不可以修改。

1、const成员函数

两个成员函数如果只是常量性不同,可以被重载。(函数名相同,内容不一样)

在类里面,把一个成员函数声明为const,要将它放在形参表()和{}之间,表示这是个const成员函数,这个成员函数不会更改类对象的内容。

深入部分:

传值,传指针,传引用的区别。

★相同点:

●都是地址的概念;

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

★不同点:

●指针是一个实体,而引用仅是个别名;

●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;

●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有     的,  前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)

●引用不能为空,指针可以为空;

●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;

●指针和引用的自增(++)运算意义不一样;

●引用是类型安全的,而指针不是 (引用比指针多了类型检查)

 

如果想在const成员里面修改class的数据成员,可以将数据声明为mutable。

2、在const和non-const成员函数中避免重复

non-const成员函数调用const成员函数,避免代码重复,但是反过来就不行,因为non-const会修改const变量值。

class TextBlock{
public:
     ...
    const char& operator[](std::size_t position) const{
         ...
         ...
         ...
         return text[position];
    }

    char& operator[](std::size_t position) {
         return 
          const_cast<char&>(
             static_cast<const TextBlock&>(*this)[position]
          );
    }
    //将op[]返回值的const转换为*this加上const调用const op[]

};    

补充:

命名的强制类型转换:

强制类型转换形式是

cast-name<type>(expression)
//其中cast-name是static_cast,dynamic_cast,const_cast,reinterpret_cast
//type是要转换的目标类型,expression是要转换的值

static_cast:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast.

double slope = static_cast<double>(j) / i;

const_cast:去掉const性质,只能改变运算对象的底层const,将常量对象转换为非常量对象的行为。,但是如果对象是一个常量,const_cast之后执行写操作就会产生未定义的后果。

不能使用const_cast改变表达式的类型,比如将const char*转换为string就是非法的,只能改变const属性。

3、reinterpret_cast(重解释转换)

比如将指向int的指针变为指向char类型的指针。

 

总结:

  • 将某些东西声明为const可帮助编译器测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
  • 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。

 

posted @ 2017-12-10 20:35  zqlucky  阅读(230)  评论(0编辑  收藏  举报