const 引用的小疑问

renyaoming 2009-02-25 01:40:09
int a=100;

const int &p=a+1; // 1

int const &p=a+1; // 2

1和2是否都是合法的

好像书上讲的都是第1种方法,能否解释一下 :)
...全文
145 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
speeder53 2009-02-25
  • 打赏
  • 举报
回复
mk
cheifer 2009-02-25
  • 打赏
  • 举报
回复
好像const放在后面在gcc编译器下会出现警告信息。
deerwin1986 2009-02-25
  • 打赏
  • 举报
回复
没区别...只是const放到后面是比较新的标准...
太乙 2009-02-25
  • 打赏
  • 举报
回复
望穿亭台水榭~~
danxuezx 2009-02-25
  • 打赏
  • 举报
回复
11 楼的正确,const顺序问题要看是用来修饰什么了,有的是一样的有的不一样,不过赞成放在前面,因为这样和所有的放在前面的意思是统一的。否则自己会给自己制造麻烦的。
herman~~ 2009-02-25
  • 打赏
  • 举报
回复
效果一样
如果用在指针

const char * p;
char * const p; 这两种就不一样
csjtxy 2009-02-25
  • 打赏
  • 举报
回复
一样的。
敬佩7楼和8楼
  • 打赏
  • 举报
回复
const int 和 int const 结果是一样的.
可以揭帖了,楼主.
waizqfor 2009-02-25
  • 打赏
  • 举报
回复
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 的存取,而直接使用立即数 1

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型,不能为其他类型?(同样在使用中不能修改)。
所以a和b是一样的,称为整型常数,在使用中不能被修改,当然都不能转为其他类型了。
#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; //a和b(其实是一样的)的行为都会出现“灾难”,在语法上讲就  b = 100.0; //是a和b都不能出现在赋值语句的左边!

  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;}
常函数只能调常函数,也是由于这个原因
redoffice 2009-02-25
  • 打赏
  • 举报
回复
给一篇我写的CONST的文章

C++中const的用法详解——V0.1
作者:XX
const 最早想法是用于取代预处理器#define 这个宏,从而形成常量的概念。
针对常量,const对象,const指针及指向const的指针,函数const类型参数,const 函数返回类
型,const类成员,及const成员函数,及对const最后理解的一些总结来描const。
cons t 对象和 cons t 类型的对象
对于这两个概念的描述如下
int const Object; //Object是一个const量是不可以被修改 Object = 2;Error
const int Object; //Object 是 const int型他所存放的内容不可以被修改
对于这两种const用于对象,表述虽然不同但是效果是一样的。因为对象本身存放着内容对
对象的改变就是对于对象内容的改变,同样改变后者也是在改变前者。所以语义上一样的。
cons t 指针 和 指向 cons t 的指针 及两者结合
对于三个概念描述如下
1.int* const p; //指针p是const不能被修改
p++; //修改p本身会Error
*p = 2; //修改p指向内容OK
2.const int* p; //p是指向一个整形常量的指针指向的内容不可以改变
p++;//OK
*p = 2; //Error
3.const int* const p; //指针p本身是不能被修改并且p所有有效的内容也不能被修改
*p = 2;//Error
p++;//Error
const 参数修饰 和 参数返回类型的 cons t 修饰
1.const 参数修饰
例如 void Fun( const int I ) { I++;} //Error不能修改常量I
2.const修饰函数返回类型
例如:const int Fun() { static int I; return I;}
int Res = (Fun())++ //Error不能修改常量返回对象
cons t 类成员 和 const 成员函数
1. const成员
类const成员在构造期间会允许被初始化并且在以后不能被改变。我们就可以知道类const
成员和一般const 变量是有所不同的,类const成员是对应于每个对象而言才有意义。因为
他在构造期被初始化,只有当类实例化后才会进行构造。所以类const成员可以这样描述:
在类的每一次实例化时被初始化,在这个对象的生存周期中不可改变。
2. const 成员函数
描述: void Class::MemberFun() const {}; //此时这个const修饰的this所有类成员变
量都不允许在这个函数体作用后被修改。这在设计上会带来一些好处,能防止你意外的处理
带来的问题。
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和非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 int* pHeap = new int;
delete pHeap;
p = NULL;//出错
解决办法是强制类型转换
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL;
const的使用注意事项
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++ 的隐
式类型转换可以起作用。临时量的生存期和引用量的生存期相同。
强传 cons t 对象可能导致无定义行为
对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数 1
const int i = 1;
*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;
所以,对 const 对象做 const_cast 可能导致无定义行为
不能将 cons t 修饰的任何对象、引用和指针作为赋值表达式的左值。
const int cx=100;
const int &rcx=cx;
const int *pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error
cons t 类型的对象不能直接被 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);
可以使用 cons t 类型别名引用 non-const 对象。此时通过 cons t 引用不能修改对象,但对象
可以通过 non-const 引用被修改。
int x=100;
int &rx=x;
const int &rcx=x; //ok
x=200;
rx=200;
rcx=200; //error
指针的属性有两个:指针的类型和指针本身的常量性。其中,指向 cons t 对象与指向 non -
cons t 对象,是不同的指针类型。
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类型的对象不能直接被nonconst
类型的指针所指示;可以使用const类型的指针指向non-const对象。
可以将相同类型(包括常量性)的 cons t 指针值赋给 non-const 指针。
int x=100;
int *px;
const int *pcx=&x;
px=pcx; //error
int *const cpx=&x;
px=cpx; //ok
若函数的返回值为内建类型或是指针,则该返回值自动成为 cons t 性质。但自定义类型则为
non-cons t 性质。
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
总结:
<1> const 常量 一般编译器不会分配空间只是维护一张表。而当extern 外部引用这个常
量或者“&”对这个常量取地址时,编译器才会为其分配地址。Const本身的机制比较复
杂。
<2> const 记忆法则 const修饰后面一个最近的名称。
<3> 对于所有非const 类型可以无条件转化为 const类型,但是后者不能自动转化为前者
除非显式的强制转化去掉const性。这样做是有意义的,因为const类型是非const的一个
子集是一种特殊,由普遍转化为特殊是合理的,就象模板特化,继承的向上映射都是有意义
的。
<4> 记住所有const修饰的内容并不是永远不可改变,如果人为的强制转化编译器是不会提
醒的。因为它没有义务这么做,所以我们对其转化时要小心。
<5> 在const类成员函数处理时,我们引入了mutable修饰类成员变量,经过其修饰的成员
变量可以在const类成员函数中被修改,编译器是允许的。而其他未被mutable修饰的成员
还是按照const规则不能在const成员函数中被改变。
const主要是为了程序的健壮型,减少程序出错.
wjksd 2009-02-25
  • 打赏
  • 举报
回复
1和2是一样的。
引用分为两种,一种是const引用,一种是非const引用。
const引用只能绑定到与自己类型相同的对象上。
非const引用可以绑定到不同但是相关的类型对象或者绑定到右值。
biweilun 2009-02-25
  • 打赏
  • 举报
回复
[Quote=引用楼主 renyaoming 的帖子:]
int a=100;

const int &p=a+1; // 1

int const &p=a+1; // 2

1和2是否都是合法的

好像书上讲的都是第1种方法,能否解释一下 :)
[/Quote]

这个顺序完全是个人喜好的问题
renyaoming 2009-02-25
  • 打赏
  • 举报
回复
int a=100;

const int &p=a+1; // 1

int const &p=a+1; // 2

1和2是否都是合法的

好像书上讲的都是第1种方法,能否解释一下 :)
yangch_nhcmo 2009-02-25
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090224/23/ade43b06-6f12-472a-8a46-2eacc8dc3848.html

详见1楼fhtingtian兄的回复:
[Quote=引用 1 楼 fhtingtian 的回复:]
转一篇有关const的文章
1、什么是const?
常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁换柱进行更新:)

2、为什么引入const?
const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

3、cons有什么主要的作用?
(1)可以定义const常量,具有不可变性。 例如:
const int Max=100; int Array[Max];
(2)便于进行类型…
[/Quote]
brookmill 2009-02-25
  • 打赏
  • 举报
回复
const int 和 int const ,效果是一样的
brookmill 2009-02-25
  • 打赏
  • 举报
回复
都是合法的,而且就是一回事
大家都习惯写第一种

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧