C++ 基本类型(Primitive Type) 的(const reference type) 参数有何用处?

原创 2014年08月17日 13:39:17

C++ 语言的复杂是众所周知的,其中const 和 reference 的语意十分复杂。其中原因,我认为很多来自于C++创始人对于“用户定义类”作为“一等公民”地位的痴迷。

他认为因该把用户定义类当作原始类同等对待。的确,他的目的从语法上来说部分达到了,但是它所衍生的复杂语意,以及编译添加的程序(compiler-instrumented-code),经常使即使经验老到的程序员混淆。

 

下面我就一个常见的问题作一番研讨:


我们知道,C++ 的const reference 参数对于函数的“非基本类”参数传递很有用,比如下面例子:

 

// simple class todemonstrate thepoint

class X

{

  private:

     int_x;

  public:

    int getX () const { return _x; }

    void setX(int x) { _x = x; }

}

 

// simple X usage

void Foo(const X &x) 

{

   x.getX();     // OK, no side effect

   x.setX(1);   // Compile Error: const cannot be changed

}

 

虽然也可用非const 传递,比如

void Bar(X &x) 

{

  x.getX();   // OK, noside effect

  x.setX(1); // OK,: can be changed

}

 

但是从程序的“寓意”上来说,Foo 不因该引入副作用(side effect), 即通过x 来改变x代表的原值。

而Bar的“寓意”因该是有副作用的,否则就不应该用X& x 而是应该用 const X &.

 

对于UDT (用户定义的类)来说,上面例子说明下面4点:

 

1)const reference 和 reference 在 runtime (运行时)语意是一样的,一般没有性能上的区别(特殊情况下,const 导致临时object,会有影响)。

2)const reference 和 reference 在编译时的语法不一样,前者不许副作用,后者是为了有副作用而设置。

3)const reference 比 reference 的范围狭窄些,是一个很好的“安全”保证,即保证你不会“无意”中修改原值。

4)const reference  的应用相比于直接“传值”(passing by value)来说,因为没有 copy 的语意,一般来说性能要好些。

 

对于原始类来说,上述区别还有意义吗?比如说

 

void AddXConst(const int & x) 有没有意义呢?


首先,我们知道 void AddXRef(int& x) 是有意义的,它可以改变原值,比如:

 

void AddX(int x)

{

    x = x +100;// local change, x referenced value not changed

}

 

void AddXRef(int& x)

{

    x = x +100;// x referenced value changed

}

 

void AddXConst(const int&x)

{

x = x +100;// error: cannot change x

int y = x+ 100;   // ok

}

 

...

int x =100;

AddX(x);

printf("%d",x); //100

AddXRef(x);

printf("%d",x);  //200

 

但是 void AddXConst(const int & x)有用吗?我们知道,在 AddXConst里,x是不能改变的 (编译出错),从寓意上来说,AddXConst应该和AddX完全一样。从性能上来说,因为AddX是传值的,AddXConst是传参考的(passingby reference),所以我的测试结果显示AddX的性能对于简单的运算来说因该是高出AddXConst的5%~30%。

 

那么,AddXConst这样的用primitiveconst reference type 参数的函数是不是画蛇添足,毫无用处呢?

 

一般来讲是的!

 

在罕见的情况下,AddXConst也是有用的:请记住const reference 的 runtime 语意,和 reference 没有区别,所以如果你想改原值,而又不得不接受const时,还是可以考虑的。比如下面“荒唐”的例子,当月亮变红时,我们改变原值:

 

int changeWhenRedMoon(const int& pi1, const int & pi2)

            {

                    // Rare condition

                       if(redMoon)

                       {

                                   const_cast<int&>(pi1)++;

                       }

 

                     // Normal condition

                        return pi1 + pi2;

            }

 

只是这种应用的机会很少,而且多半有“异味”,是设计有问题的前兆。

 

2014-8-17 美国西雅图(作者曾是微软总部13年的高级开发工程师)

 

 

 


c++之const,reference(引用),

一,尤其是在循环的时候,不要用魔数(意义没在上下文表示)。这个时候要用到魔数常量的时候,可以把该常量初始化为一个对象(变量代表一个常量): int  buf = 22;提高可读性。 二,const对象...
  • sakulamomogo
  • sakulamomogo
  • 2015年08月07日 21:41
  • 450

C++ Reference 引用用法

1. Free Standing Referenceint y; int& r = y;   定义一个引用的时候,必须初始化其值,否则编译器报错。或者 const int& q = 12;   其相...
  • RichardYSteven
  • RichardYSteven
  • 2010年11月01日 21:56
  • 7325

你知道何时调用 const_reference front() const 吗?

const_reference front() const什么时候调用
  • markjenny
  • markjenny
  • 2015年07月20日 10:14
  • 346

关于C++ const 的全面总结

C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。Const 是C++中常用的类型修饰符,常类型是指使用类型...
  • Eric_Jo
  • Eric_Jo
  • 2009年04月30日 08:54
  • 294742

c++中const的用法和注意事项

1、const修饰成员变量: 在c++中在定义常量是通常会用到的const,但是对于const的位置不同通常是表示不同的作用,而且之间的相互作用通常会造成混淆,下面作简要注解:     1)、直接修饰...
  • m0_37338590
  • m0_37338590
  • 2017年03月10日 11:34
  • 542

invalid initialization of non-const reference of type与discards qualifiers

参数传递          函数参数的传递是初始化语义:用调用者的实参去初始化函数的形参,如果参数是对象,需要调用该类的拷贝构造函数,如果没有显式定义的拷贝构造函数,则执行默认的按成员拷贝   ...
  • turkeyzhou
  • turkeyzhou
  • 2013年06月24日 15:07
  • 4236

C++编程常见问题—error: passing 'const std::map<>]' discards qualifiers或pass-by-reference-to-const-map导致的“d

产生问题的场景: int func(const map &aMap) { string value = amap[0]; } 或者 int  Test::func...
  • ai2000ai
  • ai2000ai
  • 2016年06月23日 15:31
  • 567

Oracle Type介绍

Oracle 自定义TYPE 的几种用法 Oracle中的类型有很多种,主要可以分为以下几类:  1、字符串类型。如:char、nchar、varchar2、nvarchar2。  2、数值...
  • fengshuiyue
  • fengshuiyue
  • 2014年09月01日 22:52
  • 22351

typedef和const之间的trap

 博客好久没有更新了,主要是因为工作忙,即便不忙也要看看书,工作了才发现好多东西根本就会直接忘记,因为我们工作用不到!比如c++的东西,现在连虚函数表都不快不记得了,惭愧咯!而且我还发现工作了,看书反...
  • ztz0223
  • ztz0223
  • 2009年11月04日 22:32
  • 4504

c++ pointer vs. reference

from:http://blog.csdn.net/FireCoder/article/details/5429199 Reference 1. If you are fa...
  • navyhu
  • navyhu
  • 2015年01月06日 22:14
  • 1362
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 基本类型(Primitive Type) 的(const reference type) 参数有何用处?
举报原因:
原因补充:

(最多只允许输入30个字)