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++:关于函数调用时的argument passing是by reference还是by value

2014.2 根据C++ primer 5th edition 6.2节,有个关键理解: When the argument value is "passed by value", the arg...

什么是primitive主数据类型呢

primitive就是int,double,boolean这些数据类型,它们不是对象,只是内存里的几个字节空间而已。注意int是primitive,而Integer不是!Integer是一个类。jav...
  • mlgb456
  • mlgb456
  • 2012年11月07日 15:16
  • 4622

const reference和nonconst reference的区别

普通的reference必须用与该引用同类型的对象来初始化。例如:int ival = 1024;int &refVal = ival;   // ok: refval refers to ivali...

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

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

Professional JS(三-statements&function)&(四-primitive&reference type)&黑画(5-another road)

一.Statements---flow control statements 1.if语句 ①if(condition)statement1 else statement 2.do wh...

第三节:原生数据类型使用陷阱 Pitfall of Primitive Data Type

1.Java中的原生数据类型共有8种: 1)整型:使用int表示(32位)。2)字节型:使用byte表示(表示-128~127之间的256个整数)。3)短整型:使用short表示(16位)。4)长整型...
  • lwlgkg
  • lwlgkg
  • 2011年04月26日 12:00
  • 348

【北京圣思园学习笔记】第03讲:原生数据类型使用陷阱(Pitfall of Primitive Data Type)

【Java中的原生数据类型】 1) 整型:使用int表示。(32位) 2) 字节型:使用byte表示。(表示-128~127之间的256个整数, 8位)。 3)短整型:使用short表示。(16位) ...

JavaSE第二讲:原生数据类型 Primitive Data Type

(1)编辑工具    Windows: notepad, editplus, ultraedit, gvim    Linux: vi, vim, gedit (2)Java中的数据...

JavaSE第三讲:原生数据类型使用陷阱 Ptifall of Primitive Data Type

1. Java中的原生数据类型共有8种:     1) 整型:使用int表示。(32位)     2) 字节型:使用byte表示。(表示-128~127之间的256个整数, 8位)。     3...

C++之invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’

1、看代码 2、编译结果 3、分析和解决 就拿f(a + b)来说,a+b的值会存在一个临时变量中,当把这个临时变量传给f时,由于f的声明中,参数是i...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 基本类型(Primitive Type) 的(const reference type) 参数有何用处?
举报原因:
原因补充:

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