讨论一下常引用const T& 和引用T&的区别

时间:2022-01-02 20:19:22
除了 常引用可以接收常数作为被引用对象 之外
是不是有很本质的区别??

18 个解决方案

#1


the former ,you can't change the value ,but to T &,you can do . 

#2


T&可以返回函数中被修改了的参数值,而const T& 却不能

#3


faint,这也是很明显的,
不过对于T为类的情况来说,"接收常数为被引用对象"有什么意义呢?

#4


拜托,你老兄有点糊涂吧,为什么没有意义呢?

class T;

ostream& operator<<( ostream& out, const T& obj )
{
...
}

上面这段代码不就显示了意义嘛,对于自己的维护还是别人阅读不都是一件好事吗?
难道就为了省打5个字母的时间??

#5


moonmhb()的回答是书上的标准。。。当然,仅仅是标准。

#6


我知道const T&不能改变对象的值,而T&可以
我对这个程序有疑问,希望有一个解释:
class A{
public:
A(int i) 
: n(i)
{};
A operator + ( A &a /* 把这里改为 const A &a, 下面a+1就不会出错了 */)
{ return A( n+a.n );  }
private:
  int n;
};

void main()
{
  int &j=1;       //大家都知道,这行会出错
  const int &i=1; //这行没有问题,不会出错

  A a(1);
  (void)( a+1 );  //这行编译出错!为什么上面operator+参数换成了const A&,这行就通过了
  const A& b=1;   //而这行无论如何不能通过
}

#7



你知道,你这里的a+1实际上是:a.operator+(A(1))。编译器自动生成了一个A类型的临时对象。很显然,临时对象必定是又值,必须是const的。所以这里的参数也必须是const的才能接受这个临时对象。

#8


a+1;

这行被编译器扩充为
const A tmp(1);
a.operator+(tmp);

所以你的写法不能通过。
正因如此,你的最后一行

const A& b = 1;

相当于

const A tmp(1);
const A& b = tmp;

肯定能通过,你不妨再试试。

#9


我觉得gigix的说法有点不妥。
临时对象肯定是右值,这句话仅对build-in type成立,对于user-define type是不成立的。

就以上例,operator+()返回一个临时对象。
a+A(1) = A(1);
但这句话是能通过的,

这也正是为什么对于一个class T来说,其后自增运算符要返回一个const T,而不是一个T
的原因所在。(前自增运算符需返回一个T&)。

#10


对,const A& b=1可以通过,一开始我也不知道写了什么竟然不能通过,faint
我有和你相同的想法
const A& b = 1;应该相当于
const A tmp(1);
const A& b = tmp;

但是为什么
A &b=1;
不支持生成一个中间对象这种构造方法

A tmp(1);
A &b=tmp;

是不是在语义上,b不应该是右值,所以A &b=1;编译无法通过呢?

#11


说错了,b不应该是左值

#12


你有点误会,
A &b = 1;

编译器为什么会来迁就你呢?
你再仔细想想你a+1为什么不能通过的原因。

const A tmp(1);
A &b = tmp;

这个肯定不能编译通过,编译器没有这么AI,能够根据你的意图调整为不同的作法。:)

#13


那是否是因为,如果 编译时中如果需要产生临时对象,其类型应该是const T

A &b=1;
只能相当于
const A tmp(1);
A &b=tmp;
而不是编译成我所希望的
A tmp(1);
A &b=tmp;
所以
const A &a=1; 可以通过
而A &b=1; 无法通过呢?

#14


关注,明天再来看看!

#15


明天再来:)

#16


gz up

#17


C++是强类型语言,所以 A &b=1; 这条语句试图用non-const的b引用const的1,结果当然会错。另外我认为gigix说的没错,临时对象必定为常量。a+A(1) = A(1);我想产生了两个临时对象,a+A(1)的结果是一个,保存A(1)的又是另外一个临时对象,并非a+A(1)这个临时对象。

#18


to richielee:
就是这个意思。

#1


the former ,you can't change the value ,but to T &,you can do . 

#2


T&可以返回函数中被修改了的参数值,而const T& 却不能

#3


faint,这也是很明显的,
不过对于T为类的情况来说,"接收常数为被引用对象"有什么意义呢?

#4


拜托,你老兄有点糊涂吧,为什么没有意义呢?

class T;

ostream& operator<<( ostream& out, const T& obj )
{
...
}

上面这段代码不就显示了意义嘛,对于自己的维护还是别人阅读不都是一件好事吗?
难道就为了省打5个字母的时间??

#5


moonmhb()的回答是书上的标准。。。当然,仅仅是标准。

#6


我知道const T&不能改变对象的值,而T&可以
我对这个程序有疑问,希望有一个解释:
class A{
public:
A(int i) 
: n(i)
{};
A operator + ( A &a /* 把这里改为 const A &a, 下面a+1就不会出错了 */)
{ return A( n+a.n );  }
private:
  int n;
};

void main()
{
  int &j=1;       //大家都知道,这行会出错
  const int &i=1; //这行没有问题,不会出错

  A a(1);
  (void)( a+1 );  //这行编译出错!为什么上面operator+参数换成了const A&,这行就通过了
  const A& b=1;   //而这行无论如何不能通过
}

#7



你知道,你这里的a+1实际上是:a.operator+(A(1))。编译器自动生成了一个A类型的临时对象。很显然,临时对象必定是又值,必须是const的。所以这里的参数也必须是const的才能接受这个临时对象。

#8


a+1;

这行被编译器扩充为
const A tmp(1);
a.operator+(tmp);

所以你的写法不能通过。
正因如此,你的最后一行

const A& b = 1;

相当于

const A tmp(1);
const A& b = tmp;

肯定能通过,你不妨再试试。

#9


我觉得gigix的说法有点不妥。
临时对象肯定是右值,这句话仅对build-in type成立,对于user-define type是不成立的。

就以上例,operator+()返回一个临时对象。
a+A(1) = A(1);
但这句话是能通过的,

这也正是为什么对于一个class T来说,其后自增运算符要返回一个const T,而不是一个T
的原因所在。(前自增运算符需返回一个T&)。

#10


对,const A& b=1可以通过,一开始我也不知道写了什么竟然不能通过,faint
我有和你相同的想法
const A& b = 1;应该相当于
const A tmp(1);
const A& b = tmp;

但是为什么
A &b=1;
不支持生成一个中间对象这种构造方法

A tmp(1);
A &b=tmp;

是不是在语义上,b不应该是右值,所以A &b=1;编译无法通过呢?

#11


说错了,b不应该是左值

#12


你有点误会,
A &b = 1;

编译器为什么会来迁就你呢?
你再仔细想想你a+1为什么不能通过的原因。

const A tmp(1);
A &b = tmp;

这个肯定不能编译通过,编译器没有这么AI,能够根据你的意图调整为不同的作法。:)

#13


那是否是因为,如果 编译时中如果需要产生临时对象,其类型应该是const T

A &b=1;
只能相当于
const A tmp(1);
A &b=tmp;
而不是编译成我所希望的
A tmp(1);
A &b=tmp;
所以
const A &a=1; 可以通过
而A &b=1; 无法通过呢?

#14


关注,明天再来看看!

#15


明天再来:)

#16


gz up

#17


C++是强类型语言,所以 A &b=1; 这条语句试图用non-const的b引用const的1,结果当然会错。另外我认为gigix说的没错,临时对象必定为常量。a+A(1) = A(1);我想产生了两个临时对象,a+A(1)的结果是一个,保存A(1)的又是另外一个临时对象,并非a+A(1)这个临时对象。

#18


to richielee:
就是这个意思。

#19