C++ 笔记:引用、指针和 const 限定符

引用

  • 引用必须初始化,也就是说,引用从“出生”开始就必须绑定至另一个对象,且必须“从一而终”
  • 引用必须绑定至对象,而不能绑定至字面值或表达式计算结果
  • 引用的类型要和其绑定的对象严格匹配,但有两个例外情况:
    • 可以将常量引用绑定至非常量、表达式或字面值,只要类型匹配
    • 可以将基类的引用绑定到派生类对象上
  • 引用本身不是对象,因此不存在对引用的引用
double value = 3.14159;
double &ref_value = value;
double &ref1;                       // error: 'ref1' declared as reference but not initialized
double &ref2 = 3.14159;             // error: cannot bind non-const lvalue reference of type 
                                    // 'double&' to an rvalue of type 'double'
double &ref3 = 3.14159 * value;     // error: cannot bind non-const lvalue reference of type 
                                    // 'double&' to an rvalue of type 'double'
int ival = 1;
double &iref = ival;                // error: invalid initialization of reference of type 
                                    // 'double&' from expression of type 'int'
double &ref_ref_value = ref_value;

指针

  • 指针的类型要和其指向的对象严格匹配,但有两个例外情况:
    • 可以将指向常量的指针指向非常量,只要类型匹配
    • 可以将基类的指针指向派生类对象
  • 引用不是对象,因此不存在指向引用的指针
  • 使用字面值 nullptr 来获得空指针
  • 建议初始化所有的指针,并尽量等定义了对象之后再定义指向它的指针。如果实在不清楚指针应该指向何处,就把它初始化为 nullptr 或者 0

const 限定符

  • const 对象必须初始化, 且一旦创建后其值不能改变,因此只能在 const 对象上执行不改变其内容的操作
  • 如果利用一个对象去初始化另外一个对象,则它们是不是 const 无关紧要
const int buffer_size = 1024;
int buffer1 = buffer_size;
const int buffer2 = buffer1;
const double value2;    // error: uninitialized const 'value2'
  • 默认情况下,const 对象被设定为仅在文件内有效。当多个文件中出现了同名的 const 变量时,等同于在不同文件中分别定义了独立的变量。如果想在多个文件之间共享 const 对象,必须在变量的声明和定义之前都添加 extern 关键字
// file1.cpp
extern const int buffer_size = 512;
// file2.cpp
extern const int buffer_size;

const 的引用

  • 可以将常量引用绑定至常量,两者均不可修改:
const int buffer_size = 1024;
const int &ref_buffer_size = buffer_size;
  • 也可以将常量引用绑定至非常量,只要类型匹配。但是不允许通过引用改变该非常量的值,尽管该非常量的值可以通过其他方式改变:
double value = 3.14159;
const double &ref_value = value;
value = 1.0;      // ref_value = 1.0
ref_value = 3.0;  // error: assignment of read-only reference 'ref_value'
  • 还可以将常量引用绑定至类型匹配的表达式或者字面值:
const int &ref1 = 1024;
const int &ref2 = ref1 * 2;
  • 不允许将非常量引用绑定至常量对象,因为这将存在通过非常量引用修改常量对象的风险:
const int buffer_size = 1024;
int &ref_buffer_size = buffer_size;   // error: invalid initialization of reference of 
                                      // type 'int&' from expression of type 'const int'

指向 const 的指针

const double value = 3.14159;
const double *p_value = &value;
double *p_value2 = &value; // error: invalid conversion from 'const double*' to 'double*' 
  • value 为常量,因此不能通过指针改变它的值,所以不允许将普通指针指向常量
  • 指向 const 的指针可以指向非常量,但是不允许通过该指针改变其所指对象的值:
double sqrt2 = 1.414;
const double *p_sqrt2 = &sqrt2;
*p_sqrt2 = 1.732; // error: assignment of read-only location '* p_sqrt2'
                  // 尽管 sqrt2 是非常量,但是 p_sqrt2 单方面认为 sqrt2 不可改变
                  // 另一方面 sqrt2 可以通过其他方面改变

指向非常量的 const 指针

  • 指针本身是 const,因此其值不能改变,也就是说,不能将 const 指针指向别的对象,因此 const 指针必须初始化
double value = 3.14159;
double *const p_value = &value;
value = 1.0;        // value 为非常量,可以被修改
*p_value = 2.0;     // value = 2.0,p_value 不是指向 const 的指针,可以用来改变 value 的值
double sqrt2 = 1.414;
p_value = &sqrt2;   // error: assignment of read-only variable 'p_value'
  • 尽管指针本身是 const,但其指向的值是非常量时,仍然可以通过该指针修改其指向的对象,因为这并不改变指针本身的值

指向 constconst 指针

const double value = 3.14159const double *const p_value = &value;
  • 此时指针及其指向的值都不可改变

顶层 const

  • 顶层 const:指针本身是 const
  • 底层 const:指针所指的对象是 const,或引用所绑定的对象是 const
  • 当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层 const 资格

你可能感兴趣的:(C++)