thinking in c++ 读书笔记---const

首先,普通const变量

const默认具有内部连接属性,这个可以参考连接里面的一篇文章,说的很详细.

如果让const常量可以在多个文件里面使用,必须在定义的时候指定extern.如:

extern cosnt  int i=0;

普通的const变量不会占用内存空间.但是加上extern后就会强制分配内存给这个变量.还有一种情况,在程序中用到这个const变量的地址的时候也会分配空间.

进入正题,所有的临时变量都会被默认指定为const类型.所以当你要改变一个临死变量的时候就会出错.例如:

 

// : C08:ConstReturnValues.cpp
//  Constant return by value
//  Result cannot be used as an lvalue
class  X  {
int i;
public:
X(
int ii = 0);
void modify();
}
;
X::X(
int  ii)  { i = ii; }
void  X::modify()  { i++; }
X f5() 
{
return X();
}

const  X f6()  {
return X();
}

void  f7(X &  x)  // Pass by non-const reference
x.modify();
}

int  main()  {
f5() 
= X(1); // OK -- non-const return value
f5().modify(); // OK
// Causes compile-time errors:
//! f7(f5());
//! f6() = X(1);
//! f6().modify();
//! f7(f6());
}
  ///:~其中比较难理解的是//! f7(f5());这一行.为什么这一行是错的呢?解释如下:

 

f5()直接作为f7的变量,这里实际上会出现一个临时变量.而f7又是引用传递参数,在f7里面直接操作这个临时变量,所以会出错.

所以如果f7采用值传递,或者使用const引用传递,都不会出现错误.

然后是类内部的const变量:

class  A
{
    
enum {size=9};
    
int array_2[size];
    
const int j;
    
static const int i=9;
    
int array[i];
public:
    A(
int i_j);
}
;
A::A(
int  i_j):j(i_j)
{

}

int  main ()
{
    A a(
3);
    
return 0;

}

类内部的const变量分两种,一种是非静态的.它的初始化应该在这个类的构造函数的前面,最好是放在初始化列表里面。

静态的const 变量的初始化可以在类的声明里面。如上面的程序,但是这个程序在vc里面不能不能编译通过。

静态的const变量可以直接用作数组的大小。但上面的普通const变量却不可以。

还有另外一种方法,比较古老的方法就是用一个没有标签的enum。程序中已经很清楚。

const类成员函数不会改变类成员变量。const成员函数需要在声明和定义处都带上const关键字。一个const的类对象只能调用类中的const成员函数,但实际上,const的成员函数其实也能改变类中的成员变量,方法有两种,一种是在const成员函数中,将this指针进行强制转换,使其失去const 的功能,如下:

 

class  Y  {
int i;
public:
Y();
void f() const;
}
;
Y::Y() 
{ i = 0; }
void  Y::f()  const   {
//! i++; // Error -- const member function
((Y*)this)->i++// OK: cast away const-ness
// Better: use C++ explicit cast syntax:
(const_cast<Y*>(this))->i++;
}

另外一种方法就是使用mutable 关键字,在类的声明中,在类的成员变量前加上mutable关键字,那么这个成员变量就可以在const成员函数里面改变。是合法的。

 

class  Z  {
int i;
mutable 
int j;
public:
Z();
void f() const;
}
;
Z::Z() : i(
0 ), j( 0 {}
void  Z::f()  const   {
//! i++; // Error -- const member function
j++// OK: mutable
}
v o l a t i l e的语法与c o n s t是一样的,但是v o l a t i l e的意思是“在编译器认识的范围外,这个数
据可以被改变”。不知何故,环境正在改变数据(可能通过 多任务处理),所以,v o l a t i l e告诉编
译器不要擅自做出有关数据的任何假定—在优化期间这是特别重要的。如果编译器说:“我
已经把数据读进寄存器,而且再没有与寄存器接触”。一般情况下,它不需要再读这个数据。
但是,如果数据是v o l a t i l e修饰的,编译器不能作出这样的假定,因为可能被其他进程改变了,
它必须重读这个数据而不是优化这个代码。
就像建立c o n s t对象一样,程序员也可以建立v o l a t i l e对象,甚至还可以建立const volatile对
象,这个对象不能被程序员改变,但可通过外面的工具改变。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值