解析C++中指向对象的指针使用

C++指向对象的常指针
将指针变量声明为const型,这样指针值始终保持为其初值,不能改变。

如:

  Time t1(10,12,15),t2; //定义对象
  Time * const ptr1; //const位置在指针变量名前面,规定ptr1的值是常值
  ptr1=&t1; //ptr1指向对象t1,此后不能再改变指向
  ptr1=&t2; //错误,ptr1不能改变指向

定义指向对象的常指针的一般形式为:

  类名 * const 指针变量名;


也可以在定义指针变量时使之初始化,如将上面第2, 3行合并为:

  Time * const ptr1=&t1; //指定ptr1指向t1

请注意,指向对象的常指针变量的值不能改变,即始终指向同一个对象,但可以改变其所指向对象(如t1)的值。

什么时候需要用指向对象的常指针呢?如果想将一个指针变量固定地与一个对象相联系(即该指针变量始终指向一个对象),可以将它指定为const型指针变量,这样可以防止误操作,增加安全性。

往往用常指针作为函数的形参,目的是不允许在函数执行过程中改变指针变量的值, 使其始终指向原来的对象。如果在函数执行过程中修改了该形参的值,编译系统就会发现错误,给出出错信息,这样比用人工来保证形参值不被修改更可靠。

C++指向常对象的指针变量
为了更容易理解指向常对象的指针变量的概念和使用,首先了解指向常变量的指针变量,然后再进一步研究指向常对象的指针变量。下面定义了一个指向常变量的指针变量ptr:

  const char *ptr;


注意const的位置在最左侧,它与类型名char紧连,表示指针变量ptr指向的char变量是常变量,不能通过ptr来改变其值的。

定义指向常变量的指针变量的一般形式为:

  const 类型名 *指针变量名;

几点说明:
1) 如果一个变量已被声明为常变量,只能用指向常变量的指针变量指向它,而不能用一般的(指向非const型变量的)指针变量去指向它。如:

  const char c[] ="boy"; //定义 const 型的 char 数组
  const char * pi;  //定义pi为指向const型的char变量的指针变量
  pi =c;  //合法,pi指向常变量(char数组的首元素)
  char *p2=c; //不合法,p2不是指向常变量的指针变量

2) 指向常变量的指针变量除了可以指向常变量外,还可以指 向未被声明为const的变量。此时不能通过此指针变量改变该变量的值。如:

  char cl ='a'; //定义字符变量cl,它并未声明为const
  const char *p; //定义了一个指向常变量的指针变量p
  p = &cl; //使p指向字符变量cl
  *p = 'b'; //非法,不能通过p改变变量cl的值
  cl = 'b'; //合法,没有通过p访问cl,cl不是常变量


3) 如果函数的形参是指向非const型变量的指针,实参只能用指向非const变量的指针,而不能用指向const变量的指针,这样,在执行函数的过程中可以改变形参指针变量所指向的变量(也就是实参指针所指向的变量)的值。

如果函数的形参是指向const型变量的指针,在执行函数过程中显然不能改变指针变量所指向的变量的值,因此允许实参是指向const变量的指针,或指向非const变量的指针。如:

  const char str[ ] = "boy"; //str 是 const 型数组名
  void fun( char * ptr) ; //函数fun的形参是指向非const型变量的指针
  fun(str); //调用fun函数,实参是const变量的地址,非法

因为形参是指向非const型变量的指针变量,按理说,在执行函数过程中它所指向的变量的值是可以改变的。但是形参指针和实参指针指向的是同一变量,而实参是const 变量的地址,它指向的变量的值是不可改变的。这就发生矛盾。因此C++要求实参用非const变量的地址(或指向非const变量的指针变量)。

上表的对应关系与在(2)中所介绍的指针变量和其所指向的变量的关系是一致的: 指向常变量的指针变量可以指向const和非const型的变量,而指向非const型变量的指针变量只能指向非const的变量。

以上介绍的是指向常变量的指针变量,指向常对象的指针变量的概念和使用是与此类似的,只要将“变量”换成“对象”即可。

1) 如果一个对象已被声明为常对象,只能用指向常对象的指针变量指向它,而不能用一般的(指向非const型对象的)指针变量去指向它。

2) 如果定义了一个指向常对象的指针变量,并使它指向一个非const的对象,则其指向的对象是不能通过指针来改变的。如:

  Time t1(10,12,15); //定义Time类对象t1,它是非const型对象
  const Time *p = &t1; //定义p是指向常对象的指针变量,并指向t1
  t1.hour = 18; //合法,t1不是常变量
  (* p).hour = 18; //非法,不齙通过指针变量改变t1的值

如果希望在任何情况下t1的值都不能改变,则应把它定义为const型,如:

  const Time t1(lO,12,15);

请注意指向常对象的指针变量与指向对象的常指针变量在形式上和作用上的区别。

  Time * const p; //指向对象的常指针变量
  const Time *p; //指向常对象的指针变量

3) 指向常对象的指针最常用于函数的形参,目的是在保护形参指针所指向的对象,使它在函数执行过程中不被修改。

请记住这样一条规则: 当希望在调用函数时对象的值不被修改,就应当把形参定义为指向常对象的指针变量,同时用对象的地址作实参(对象可以是const或非const型)。如果要求该对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应把它定义为const型。

4) 如果定义了一个指向常对象的指针变量,是不能通过它改变所指向的对象的值的,但是指针变量本身的值是可以改变的。