const用法

const的几种用法:

  1.const用来限制变量
    const int a;         //a的值为不可变
    const int *p;       //*p的值为不可变
    int* const p;       //p值为不可变
    const int* const p; //p的值不可变,*p也不可变
  2.cosnt用来限定函数
    const int fun(void) //函数的返回值为不可变
    int fun(void) const  //函数不可以改变对象的状态。
                         //编译器将不允许此方法的任何数据成员执行赋值,自增,或自减操作
                         //也不允许此方法调用这一类的任何非常量方法
                         //对于常量对象只能调用声明为const的方法

说明: 可以使用const_case来解除const属性

上述用法用下列的例子来说明:

#include <iostream>
using namespace std;

class test
{
public:
 test(void) { cout<<"Test"<<endl; }
 ~test(void) { cout<<"~Test"<<endl; }

 void fun(void) { cout<<"Fun"<<endl; }
 void fun1(void) const
 {
  //a = 3;//error
  //fun();//error
  fun2();//ok
  cout<<"Fun1"<<endl;
 }
 void fun2(void) const
 {
  cout<<"Fun2"<<endl;
 }
 const int fun3(void)
 {
  return 5;
 }
 int a;
};

int _tmain(int argc, _TCHAR* argv[])
{
 const int a = 3;
 //a = 4;//error

 int b = 4;

 const int *cp = &b;
 cp = &a;//ok
 //*cp = 65; //error

 int* const pc = &b;
 //pc = &a;//error
 *pc = 65;//ok

 const int* const cpc = &b;
 //cpc = &a;  //error
 //*cpc = 65; //error

 const test oTest;
 //oTest.fun();//error
 oTest.fun1();//ok
 oTest.fun2();//ok

 test oTest1;
 //int c = oTest.fun3();//error
 const int c = oTest1.fun3();
 
 return 0;
}

 (2)

const主要是为了程序的健壮型,减少程序出错.
最基本的用法
:
const int a=100; b
的内容不变,b只能是100也就是声明一个int类型的常量
(#define b =100)
int const b=100; //
和上面作用一样
 

const
指针和引用一般用在函数的参数中

int* m = &a; //
出错,常量只能用常指针
int c= 1;const int*pc = &c;//
常指针可指向常量 

const int* pa = &a; //
指针指向的内容为常量(就是b的值不变
)
int const *a = &b; //
指针指向的内容为常量(就是b的值不变
)*p=3//error
int* const a = &b; //
指针为常量,不能更改指针了如 a++但可以改值
*p=3; 

从这可以看出const放在*左侧修饰的是指针的内容,const放在*右侧修饰的是指针

本身

const
引用的用法和指针一样

int const & a=b;
和指针一样
const int& a=b;
和指针一样
但没有 int& const a=b 的用法因为引用不能做移位运算,但只是出个warning 

const int* const a = &b; //
综合应用,一般用来传递多维的数组

类如:char* init[] = {"Paris","in the","Spring"};
void fun(const int* const a){}
fun(init)//
保护参数不被修改
 

int A(int)const; //
是常函数,只能用在类中,调用它的对象不能改改变成员值

const int A(); //
返回的是常量,所以必须这么调用 cosnt int a=A();
int A(const int); //
参数不能改值,可用在任意函数

int A(const int*);
....
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 

const int* pHeap = new int;
delete pHeap;
p = NULL;//
出错
我的解决办法是强制类型转换
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL; 

一、const 和引用联合使用的时候要注意 

const int a = 1; 
const int& ref1 = a;
const int& ref2 = 1; 

ref1
ref2 都是正确的,但是他们引用的内容和一般的引用不同

const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1
实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。 

二、强传const对象可能导致无定义行为
 

对于优化做的比较好的编译器,代码
const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数


const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为

目前我就遇到这些问题,那位还有补充的吗 





能不能把自己的经验也谈谈。大家交流交流

这个就是我在调错时发现的
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 





Thinking again in C++
(一)常量性原理 cphj(原作) 
有些地方很受启发
 


1.
不能将const修饰的任何对象、引用和指针作为赋值表达式的左值。

const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error 

2.const
类型的对象不能直接被non-const类型的别名所引用。
(1)
不能将const类型的对象传递给non-const类型的引用。
const int cx=100;
int & rx=cx; //error
(2)
不能将const类型的实参传递给形参为non-const类型引用的函数。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
(3)
不能将const类型的对象作为non-const类型引用的函数返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x); 

3.
可以使用const类型别名引用non-const对象。此时通过const引用不能修改对象,但对象可以通过non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error 

4.
指针的属性有两个:指针的类型和指针本身的常量性。其中,指向const对象与指向non-const对象,是不同的指针类型。
int x=100;
const int * pcx=&x; //[1]
int * px=&x; //[2]
int y=100;
int * const cpy=&y; //[3]
int * py=&y; //[4]
[1][2]
两个指针的类型不同;[3][4]两个指针的常量性不同。
对象与指向对象的指针的规则类似于对象与引用。即,const类型的对象不能直接被non-const类型的指针所指示(同2);可以使用const类型的指针指向non-const对象(同3)。 

5.
可以将相同类型(包括常量性)的const指针值赋给non-const指针。

int x=100;
int * px;
const int * pcx=&x;
px=pcx; //error
int * const cpx=&x;
px=cpx; //ok 

6.
若函数的返回值为内建类型或是指针,则该返回值自动成为const性质。但自定义类型则为non-const性质。
int f() //
相当于返回const int
{
return 100;
}
int * g(int & ra) //
相当于返回
int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //
返回的就是
CTest
{
return CTest(200);


f()=200; //error 

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
*g(y)=x; //ok
,从这点可以看出g()返回的不是
const int * 

CTest t(100);
h()=t; //ok
,但却是完全错误的、危险的做法

//
所以h()的正确写法是返回const CTest





const int b=100; b
的内容不变,b只能是
100
int const b=100; b
必须为int,不能为其他类型
?
2句话的意思应该是一样的吧 , THINKING IN C++是这样说的






const int a=100; a
的内容不变,a只能是100(同样不能类型转换)。
int const b=100; b
必须为int,不能为其他类型?(同样在使用中不能修改)。
所以ab是一样的,称为整型常数,在使用中不能被修改,当然都不能转为其他类型了。 
#include <iostream> 

using namespace std; 

int main()
{
  
const int a = 100;
  
int const b = 100; 

  a = 100; //这四条语句编译时都会出现“
Cannot modify a const object 
b = 100; //in function main()
”的错误提示,也就是说,任何企图修改   a = 100.0; //ab(其实是一样的)的行为都会出现“灾难”,在语法上讲就  b = 100.0; //ab都不能出现在赋值语句的左边!
 

  
cout<<'/n'<<a<<'/n'<<b<<endl; 

  
return 0;
}





常函数的调用是这样的:常量对象只能调用常成员函数,非常量对象即可以调常成员函数,也可以调一般成员函数,但当某个函数有const和非const两个版本时,const对象调const版本,非const对象调非const版本

例:
class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;

A a;
a.GetData();//
调用int & GetData(){return data;}
//
但如果没有这个函数,也可以调用
const int & GetData()const 
const A const_a;
const_a.GetData();//
调用
const int & GetData()const {return data;}
常函数只能调常函数,也是由于这个原因






算你狠!加两点

一、const 和引用联合使用的时候要注意 

const int a = 1; 
const int& ref1 = a;
const int& ref2 = 1; 

ref1
ref2 都是正确的,但是他们引用的内容和一般的引用不同

const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1
实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。 

二、强传const对象可能导致无定义行为
 

对于优化做的比较好的编译器,代码
const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数


const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为






#include <iostream.h>
void fun(char b){cout <<"void"<<endl;}
int fun(int const b){cout <<"int"<<endl;} 
int main()
{
fun(1.0);//
详细看看重载函数吧 
fun(4); //
想一想调用哪一个
 

return 0;
}
我试了一下,会出错? vc说:
'fun':ambiguous call to overloaded function 





补充的好啊,这个一般不会注意的

const int i = 1;
*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;
这个可真有意思,调试时两个都是2,可编译就是21
const
的永远都是const,这样能更改就不错了,不然就自相矛盾了
奇怪的是 pi &i地址一样啊,就像楼上说的这是编译时的优化
处理
const int i = 1;
int* pi=const_cast<int*>(&i);
*pi=2;
cout << *pi << endl;
cout << i << endl; 





那个主要是隐式转换
你可依次把两个函数注掉看看调用
#include <iostream.h>
//void fun(char b){cout <<"void"<<endl;}
void fun(int b){cout <<"int"<<endl;}
int main()
{
fun('a');
fun(4); 
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值