const限定修饰符用法总结(常量,指针,迭代器,函数参数,成员函数)

转自:http://blog.csdn.net/youxueT_T/article/details/7606446


const限定修饰符用法总结(常量,指针,迭代器,函数参数,成员函数)

在这里总结一下const限定修饰符的各种用法,都已经过vs2010测试。

1)  声明及初始化const常量。

在声明一个const常量时,必须对其初始化,否则会报错。和引用& 一样,必须初始化,初始化之后不能再改!!

1 const int constvar;         //error
2 const int constvar = 10;    //ok

但是,有一个例外的情况,就是extern进来的const常量不需要初始化(如果该常量其他地方确实有出现,这时将它extern进来并且初始化反而会出错)。因为如果你在有extern的时候还初始化就说明这是一个定义而不是声明了,而extern是在头文件中声明一个变量的时候用的。

1 extern const int externvar;

2)  指针。

参考:http://blog.csdn.net/hlsdbd1990/article/details/45643643

对于指针变量有以下四种情况(这四句是不完整的,其中有些必须在声明时进行初始化,否则会出错,故未写分号^^):

a int *ptr1=0; //定义一个指针的时候最好初始化,这样指针不至于不知道指向哪里。
b const int *ptr2;//定义一个指向const 类型的int型变量的指针,指针不是const类型,所以不需要初始化。可以初始化为const和非const的对象
c int *const ptr3;//定义一个指向int类型的const指针,必须初始化。初始化为非const的对象,不能初始化为const对象
d const int *const ptr4;//定义一个指向const对象的const指针,必须初始化,初始化的对象必须是const

a)  指向非const对象的指针。

试图将非const对象的指针指向一个常量对象将引起编译错误,即下面的语句将不能通过编译。

1 int *ptr1 = &constvar;      //error

原因很简单。如果可以编译成功,我们则可以通过类似*ptr1=100这样的语句修改constvar常量的值(由于编译器不能跟踪指针在程序中任意一点指向的对象是否为常量,所以是可以赋值成功的)。这样一来就不能称之为常量了。

b)  指向const对象的指针。

与a做对比,此时由于ptr2指向的是一个const常量,所以就可以将它赋值为const常量的地址了。

1 const int *ptr2 = &constvar;    //ok

此时,由于ptr2指向的对象是常量,所以不能通过指针修改常量的值。但是,由于指针本身不是常量,所以可以修改指针,令其指向其他常量,甚至可以令其为0。

1 *ptr2 = 100;                     //error
2 const int constvar2 = 100;        
3 ptr2 = &constvar2;               //ok
4 ptr2 = 0;                        //ok

另外,也可以令ptr2指向一个变量(非常量),但是也同样,不能通过指针修改变量的值,如下:

1 int nonconst = 1000;
2 ptr2 = &nonconst;             //ok
3 *ptr2 = 10000;                //error

c)  const指针,指向const或非const对象。

声明const指针时,必须同时对其进行初始化。

1 int nonconst = 1000;
2 int *const ptr3;                //error
3 int *const ptr3 = &nonconst;    //ok

如果,ptr3指向的是一个非const对象,可以通过ptr3修改该对象的值,但是不能修改ptr3指针本身的值,如下:

1 *ptr3 = 10000;        //ok
2 ptr3 = &constvar;     //error

d)  指向const对象的const指针。

终于最后一个了。这种指针,就是把前面的几个结合起来。声明时必须初始化,指针指向的对象以及指针本身都不能修改。

3)  迭代器。

const_iterator用于遍历const容器。

1 const vector<int> constvector;
2 vector<int>::iterator  it = constvector.begin();          //error
3 vector<int>::const_iterator  it = constvector.begin();    //ok

const_iterator保证是以只读的方式访问容器元素,不得通过迭代器修改容器元素的值。

1 *it = 20;    //error

4)  函数参数。

参数传值还是传指针还是传引用的问题这里就不啰嗦了。

当参数为引用时,如果不希望引用参数在被调用的函数内部被修改,就可以使用const修饰符修饰引用参数。

一般情况下,为了避免复制引起的开销,可以将形参声明为const类型的引用。因为const类型能够接受const和非const类型的实参。

http://blog.csdn.net/hlsdbd1990/article/details/45874613

1 void func(const int& var)
2 {
3     var = 100;        //error
4 }

用const修饰传值参数是没有任何意义的,因为传值本身就是传入一个实参的副本,并不会修改实参(刚入职时,我就犯了这个低级的错误--|)。

5)  const成员函数

在有些类的成员函数中,往往会看到在参数列表的最后有一个const修饰符,形如:

复制代码
 1 class test
 2 {
 3 public:
 4     int getVar() const 
 5     { 
 6         return var;        //ok
 7     }
 8     void setVar(const int& aVar) const
 9     {
10         var = aVar;        //error
11     }
12 
13 private:
14     int    var;
15 };
复制代码
http://blog.csdn.net/hlsdbd1990/article/details/46548651
如果成员函数只是在类中声明,在类外定义,那么定义时必须加上类作用域运算符,例如上面的setVar函数如果是在类外定义,那么必须写成
void  test::setVar(const int& aVar) const
 9     {
10         var = aVar;        //error
11     }

a) 用const修饰成员函数,表明不能通过调用该成员函数修改私有成员如果一定想要修改通过const的成员函数来修改私有成员,那么私有成员就必须声明为mutable类型。

http://blog.csdn.net/hlsdbd1990/article/details/46547115

如上例中setVar函数由于修改了test类中的var成员变量,所以不能使用const限定符修饰。

b) 对于在类外定义的成员函数,必须在成员函数的定义和声明中都指定关键字const,不然将被视为重载,如下:

复制代码
 1 class test
 2 {
 3 public:
 4     int getVar() const;
 5 private:
 6     int    var;
 7 };
 8 
 9 int test::getVar()        //error:overloaded member function not found in 'test'
10 {
11     return var;        
12 }
复制代码

c) const类对象只能调用其const成员函数(除了构造函数和析构函数,后面详解)。

复制代码
 1 class Test
 2 {
 3 public:
 4     int getVar(){ return var; }
 5 private:
 6     int    var;
 7 };
 8 
 9 int main()
10 {
11     const Test consttest;
12     consttest.getVar();        //error
13 
14     return 0;
15 }
复制代码

第12行语句将报错,由于Test类并没有定义一个const版本的getVar()成员函数。

但是,这种情况有一个例外,就是构造函数和析构函数。即使构造函数和析构函数不是const的,const类对象也同样可以调用它们。所以一个const类对象“从构造完成时刻到析构开始时刻”这段时间被认为是const的(尝试将构造函数写为const,不过报错了)。

d) 如果一个类含有指针,那么在const成员函数中还是可以修改指针所指的对象。其实想想这句话也比较好理解,指针的值是不能修改的,但是指针所指的对象是可以修改的。


e) 构造函数不能声明为const

f) static成员不是任何对象的组成部分,所以static成员函数不能声明为const.

6)  const成员变量

http://blog.csdn.net/hlsdbd1990/article/details/46609533

  • static数据成员必须在类定义体的外部定义(正好一次)。不像普通数据成员,static数据成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。

  • 整型const static数据成员就可以在类的定义体中进行初始化。




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值