关于const的总结

最近看完了Stanley B.Lippman的c++ primer,觉得里面有很多知识点涉及到了const,所以就翻了翻原书,找到其中的知识点。

一、const最简单是将对象定义为常量,因为常量在定义后不能修改,所以定义时必须初始化。

const std::string hi = "hello";//可以,初始化成功

const int i,j = 0;        //error,i 没有初始化

二、const默认为文件的局部变量,非const变量默认为extern,所以要使const能够在其他的文件中访问,必须显示的指定为extern。如下:

文件file1.cc

extern const int bufferSize = fun();

文件file2.cc

extern const int bufferSize;//注意这里的const对象没有初始化,初始化工作是在文件file1中进行的。

for(int index = 0;index!=bufferSize;++index)

三、const和引用,const引用是指向const的引用

const int ival = 1024;

const int &refVal = ival;

int &ref2 = ival        //错误,将一个const指向了非const对象

const 引用可以初始化为不同类型的对象或者初始化为右值,如字面常量

int i = 23; 

const int &r = 42;

const int &r2 = i ;  

上述三行代码编译器会转换为如下的编码

int temp = i;

const int &r2 = temp

四、指针和const限定符

1、指向const对象的指针,c++强制要求指向const对象的指针也必须具有const特性。

const double *cptr;  //cptr是指向double类型的const对象的指针,const限定的是指针指向的对象而非指针本身。

把一个const对象的地址赋给一个普通的非const对象的指针也会导致编译错误:

const double pi = 3.14;

double *ptr = π//错误,ptr是普通指针

const double *cptr = π//正确

不能用void *保存const对象的地址,必须使用const void*保存其地址

const int universe = 42;

const void *cpv = &universe;//OK

void *pv = &universe;//Error

允许把非const对象的地址赋给指向const对象的指针

double dval = 3.14;

cptr = &dval;//但是不能通过cptr改变dval的值

const指针:本身的值亦不能修改

int errNum = 0;

int *const curErr = &errNum;//curErr就是一个const指针,既然是const对象就必须初始化,指针指向对象的属性能不能修改完全取决于该对象自己

指向const对象的const指针

const double pi = 3.14;

const double *const pi_ptr = π//既不能修改pi_ptr也不能修改pi

const既可以放在类型前也可以放在类型后

const int s1;//s1s2是同一种类型

int const s2;

const对象的动态分配和回收

c++允许创建const对象,如下:

const int *pci = new const int(1024);//如其他常量一样,一经初始化就不能改变。

const对象的删除

delete pci;//即使delete表达式的操作数是指向int型的指针,也照删不误

const形参,

1void fun(const int i);//则在函数中不能改变实参的局部副本,实参仍以副本的形式传递因此传递给fun的既可以是const对象也可以是非const对象。

2)使用const引用避免复制,在传递大型对象时,需要使用引用形参

bool isShorter(const string &s1,const string &s2){

return s1.size()<s2.size();//由于string对象可能相当长,我们希望避免复制

}                                //操作

如果函数具有非const引用形参,则不能通过const进行调用

可基于函数的引用形参是指向const对象还是指向非const对象来实现函数的重载

int lookup(int &);

int lookup(const int &);//重载函数,不能基于指针是否为const来重载函数:

int fun(int *);

int fun(int *const);//这样是错误的

七、将const加在形参列表之后就可以将成员函数生明为常量

int fun() const;//const成员不能改变其操作的对象的数据成员,const必须同时出现在生明和定义中。其中构造函数声明为const是不必要的,不管对象是否为const,都用一个构造函数来初始化对象。

八、this指针中的应用

简单回顾this指针

class Screen{

public:

typedef std::string::size_type index;

Screen& move(index r,index c);

Screen& set(char);

Screen& set(index,index,char);

private:

std::string contents;

index cursor;

index height,width;

};

Screen& Screen::move(index r,index c){

index row = r * width;

cursor = row + c;

return *this;

}

Screen::set(char){

contents[cursor] = c;

return *this;

}

在普通非const成员函数中,this指针式指向类型是const的指针,可以改变this所指向的值,但是不能改变this所保存的地址,在const成员函数中,this指针是指向const类型对象的const指针。既不能改变this所指向的值也不能改变保存this指针的地址。若将display()改成了const,则会出错。

基于成员函数是否为const可以重载一个函数,同样,基于一个指针形参是否指向const可以重载一个函数,const对象只能使用const成员,非const对象可以使用任意成员

class Screen{

public:

Screen& display(std::ostream &os){

do_display(os);

return *this;

}

const Screen& display(std::ostream& os)const{

do_display(os);

return *this;

}

private:

void do_display(std::ostream &os)const{

os<<content;

}

};

九、特殊整形const static成员

一般而言,类的static成员,像普通数据成员一样,不能在类的定义中初始化。相反,类的static成员数据通常在定义时才初始化。

这个规则的一例外就是,是要初始化式是一个常量表达式,整型const static数据成员就可以在类的定义中初始化:

class Account{

public:

static double rate(){return interestRate;}

static void rate(double);

private:

static const int period = 30;

double daily_tbl[period];

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值