c & c++中const

1 const的基本用法

  常变量:  const 类型说明符 变量名 #在c语言中,仍是一个变量。c++中则变为一个常量,比如可以设置为数组的长度

  常引用:  const 类型说明符 &引用名

  常对象:  类名 const 对象名

  常成员函数:  类名::fun(形参) const

  常数组:  类型说明符 const 数组名[大小]    

  常指针:  const 类型说明符* 指针名 ,类型说明符* const 指针名

const” 与 “类型说明符”或“类名”(其实类名是一种自定义的类型说明符) 的位置可以互换。如:

     const int a=5; 与 int const a=5; 等同

     类名 const 对象名 与 const 类名 对象名 等同

  )

2 具体用法

(1)常量指针和指针常量

    使用指针时涉及到两个对象:该指针本身和被它所指的对象。
指针常量: char *const cp; //到char的const指针
常量指针: char const *pc1; //到const char的指针
常量指针: const char *pc2; //到const char的指针(后两个声明是等同的)
从右向左读的记忆方式:
cp is a const pointer to char. 故cp不能指向别的字符串,但可以修改其指向的字符串的内容
pc2 is a pointer to const char. 故*pc2的内容不可以改变,但pc2可以指向别的字符串

记忆方法:* (指针)和 const(常量) 谁在前先读谁 ;*象征着地址,const象征着内容;谁在前面谁就不允许改变

且注意:允许把非 const 对象的地址赋给指向 const 对象的指针,不允许把一个 const 对象的地址赋给一个普通的、非 const 对象的指针。

a) 对于常量指针,不能通过该指针来改变所指的内容。即,下面的操作是错误的:

      int i = 10;

      const int *pi = &i;

      *pi = 100;

      因为你在试图通过pi改变它所指向的内容。

b)  对于指针常量,不能将指针再指向其他的内容。

      int i =100;

      int j = 200;

      char *const p = &i;

      p = &j; #不允许这样

(2)常量引用

引入常量引用是为了避免在使用常量引用时修改了所指向变量的值,同时也不可以再指向其他变量。

int c = 10,d = 20;

const int& b = c;

b = 20; #错误

b = d; #错误

另外常量引用可以进行非左值赋值。例如 const int& e = 10;但是int& e = 10是不可以的

(3)常量函数

常量函数是C++对常量的一个扩展,它很好的确保了C++中类的封装性。在C++中,为了防止类的数据成员被非法访问,将类的成员函数分成了两类,一类是常量成员函数(也被称为观察着);另一类是非常量成员函数(也被成为变异者)。在一个函数的签名后面加上关键字const后该函数就成了常量函数。对于常量函数,最关键的不同是编译器不允许其修改类的数据成员。例如:

    class Test

    {

    public:

    void func() const;

    private:

    int intValue;

    };

    void Test::func() const

    {

    intValue = 100;

    }

    上面的代码中,常量函数func函数内试图去改变数据成员intValue的值,因此将在编译的时候引发异常。

    当然,对于非常量的成员函数,我们可以根据需要读取或修改数据成员的值。但是,这要依赖调用函数的对象是否是常量。通常,如果我们把一个类定义为常量,我们的本意是希望他的状态(数据成员)不会被改变。那么,如果一个常量的对象调用它的非常量函数会产生什么后果呢?看下面的代码:

    class Fred{

    public:

    void inspect() const;

    void mutate();

    };

    void UserCode(Fred& changeable, const Fred& unChangeable)

    {

    changeable.inspect(); // 正确,非常量对象可以调用常量函数。

    changeable.mutate(); // 正确,非常量对象也允许修改调用非常量成员函数修改数据成员。

    unChangeable.inspect(); // 正确,常量对象只能调用常理函数。因为不希望修改对象状态。

    unChangeable.mutate(); // 错误!常量对象的状态不能被修改,而非常量函数存在修改对象状态的可能

    }

    从上面的代码可以看出,由于常量对象的状态不允许被修改,因此,通过常量对象调用非常量函数时将会产生语法错误。实际上,我们知道每个成员函数都有一个隐含的指向对象本身的this指针。而常量函数则包含一个this的常量指针。如下:

    void inspect(const Fred* this) const;

    void mutate(Fred* this);

     也就是说对于常量函数,我们不能通过this指针去修改对象对应的内存块。

(4) 常量返回值

很多时候,我们的函数中会返回一个地址或者引用。调用这得到这个返回的地址或者引用后就可以修改所指向或者代表的对象。这个时候如果我们不希望这个函数的调用这修改这个返回的内容,就应该返回一个常量

const int Fun();

(5)c++中类的const成员变量

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。如

class A

{

 const int size = 100;    //错误

 int array[size];         //错误,未知的size

}
const数据成员的初始化只能在类的构造函数的初始化列表中进行。

原文地址:https://www.cnblogs.com/yxzfscg/p/4753262.html