c++基础分析(三)

2014-11-24 10:20:26 · 作者: · 浏览: 4
合法
如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。

3.3. const 成员函数
任何不会修改数据成员(即函数中的变量)的函数都应该声明为const 类型。如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,这无疑会提高程序的健壮性。以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。编译器将指出GetCount 函数中的错误。

const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
关于Const函数的几点规则:
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
d. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的。

4.C++引用详解

4.1、引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。

  例如: Point pt1(10,10);

  Point &pt2=pt1; 定义了pt2为pt1的引用。通过这样的定义,pt1和pt2表示同一对象,具有相同的地址。

  需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。因此,当下面的语句执行后:

  pt1.offset(2,2);

  pt1和pt2都具有(12,12)的值。

  引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才初始化它。例如下面语句是非法的:

  Point &pt3;

  pt3=pt1;

4.2、引用参数

  1、传递可变参数

  传统的c中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。

  所以在传统的c中,如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。比如,实现

  两整数变量值交换的c程序如下:

  void swapint(int *a,int *b)

  {

  int temp;

  temp=*a;

  *a=*b;

  *b=temp;

  }

  使用引用机制后,以上程序的c++版本为:

  void swapint(int &a,int &b)

  {

  int temp;

  temp=a;

  a=b;

  b=temp;

  }

  调用该函数的c++方法为:swapint(x,y); c++自动把x,y的地址作为参数传递给swapint函数。

  2、给函数传递大型对象

  当大型对象被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的副本,也就是参数传递时,对象无须复制。

4.3、引用返回值

  如果一个函数返回了引用,那么该函数的调用也可以被赋值。这里有一函数,它拥有两个引用参数并返回一个双精度数的引用:

  double &max(double &d1,double &d2)

  {

  return d1>d2 d1:d2;

  }

  由于max()函数返回一个对双精度数的引用,那么我们就可以用max() 来对其中较大的双精度数加1:

  max(x,y)+=1.0;

  4.5、常引用

  常引用声明方式:const 类型标识符 &引用名=目标变量名;

  用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。

int a ;
const int &ra=a;
ra=1; //错误
a=1; //正确

  这不光是让代码更健壮,也有些其它方面的需要。

  假设有如下函数声明:

string foo( );
void bar(string & s);

  那么下面的表达式将是非法的:

bar(foo( ));
bar('hello world');

  原因在于foo( )和'hello world'串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。

引用型参数应该在能被定义为const的情况下,尽量定义为const 。

4.6、引用和指针的混用

在堆中创建一块内存区域,必须要用指针指向它,否则该区域空间无法访问,当然我们可以用引用来引用指向内存空间的指针,如:

int *p = new int;

int &r = *p;

这样r就成了指针p读取到的值的别名,我们可以将4赋给*p的别名:

r = 4;

cout << *p; //值为4

但是,我们不能直接引用来指向堆中新建空间,因为这个引用只是别名,它不可以作为指针使用,如:

int &r = new int; //这样是错误的。

它会提示不能将指针转化为引用,因此需要加上星号(*),如:

int *&r = new int; //正确

其意思是创建一个对空间,定义&r作为该空间的引用,这样r就成了该空间的别名。