一、对象指针
(1)指向对象的指针
对象空间的起始地址就是对象的指针,定义一个指针变量,用来存放对象的地址,这就是指向对象的指针变量
指向类对象的指针变量的格式为:类名 * 对象指针名
Time * pt; 定义pt为指向Time类对象的指针变量
Time t; 定义t为Time类对象
pt = &t; 将t的起始地址赋给pt
这样,pt就是指向Time类对象的指针变量,它指向对象t
* pt pt所指向的对象,即t
(*pt).hour pt所指向的对象中的成员,即t.hour
pt->hour pt所指向的对象中的成员,即t.hour
(2)指向对象成员的指针
存放对象成员地址的指针变量就是指向对象成员的指针变量
1.指向对象成员变量的指针
命名格式为:变量类型名 * 指针变量名 int * p(定义指向整型数据的指针变量)
p = &t.hour 将对象t的成员hour的地址赋给p,p指向t.hour
cout<<*p<<endl 输出t.hour的值
2.指向对象成员函数的指针
命名格式为:函数类型(类名:: * 指针变量名)(参数列表)
void(Time:: * p)() 定义p为指向Time类中成员函数的指针变量
使指针变量指向一个公用成员函数的格式为:指针变量名 = & 类名:: 成员函数名
p = &Time:: get_time;
二、const成员
(1)const对象
命名格式为:类名 const 对象名(实参表) 或 const 类名 对象名(实参表)
const Time t(8,8,8) 定义t是常对象,在t的整个生命周期中,t的所有成员的值都不能被修改
t.get_time() 调用常对象t中的成员函数,非法操作
void get_time() const 定义一个const成员函数,可以访问const对象中的成员变量,但不允许修改成员变量的值
(2)const对象成员
1.const成员变量
用const修饰的成员变量的值是不能改变的,只能通过构造函数的参数初始化表对成员变量进行初始化,任何其他函数都不能对成员变量赋值
命名格式为:const 变量类型 变量名
const int hour 定义hour为const成员变量
2.const成员函数
const修饰的成员函数只能引用本类中的成员变量,而不能修改它们。const是函数类型的一部分,在声明函数和定义函数的时候都要有const关键字,在调用时不必加const
命名格式为:类型名 函数名(参数列表)const
void get_time() const 定义一个const成员函数,注意const在函数名和括号之后
成员变量 | 非const成员函数 | const成员函数 |
非const成员变量 | 可以引用,也可以改变值 | 可以引用,不可以改变值 |
const成员变量 | 可以引用,不可以改变值 | 可以引用,不可以改变值 |
const对象 | 不允许 | 可以引用,不可以改变值 |
class Time
{
public:
void get_time()
{
cout << "get_time()" << endl;
cout << "hour:" << _hour << endl;
cout << "minute:" << _minute << endl;
cout << "second:" << _second << endl << endl;
}
void get_time() const
{
cout << "get_time() const" << endl;
cout << "hour:" << _hour << endl;
cout << "minute:" << _minute << endl;
cout << "second:" << _second << endl;
}
private:
int _hour; // 时
int _minute; // 分
int _second; // 秒
};
int main()
{
Time t1;
t1.get_time();
const Time t2;
t2.get_time();
getchar();
return 0;
}
注意:
在一个类中,如果有些成员变量的值允许改变,另一些成员变量的值不允许改变,则可以将一部分成员变量声明为const,以保证其值不被改变,可以用非const的成员函数引用这些成员变量的值,并修改非const成员变量的值。
如果要求所有的成员的值都不允许修改,则可以将所有的成员声明为const,或将对象声明为const,然后用const成员函数引用数据成员,这样起到“双保险”的作用,切实保证了数据成员不被修改。
如果已定义了一个const对象,只能调用其中的const成员函数,而不能调用非const成员函数(无论这些函数是否会修改对象中的数据)。这是为了保证数据的安全。如果需要访问const对象中的数据成员,可将const对象中的所有成员函数都声明为const成员函数,并确保在函数中不修改对象中的数据成员。
不要误认为const对象中的成员函数都是const成员函数。const对象只保证其数据成员是const数据成员,其值不被修改。如果在const对象中的成员函数未加const声明,编译系统把它当做非const成员函数处理。
const成员函数内可以调用其他的const成员函数,不能调用另一个非const成员函数。
非const对象可以调用非const成员函数和const成员函数。
非const成员函数内可以调用非const成员函数和其他const成员函数。
(3)指向对象的const指针
将指针变量声明为const型,这样指针变量始终保持为初值,不能改变,即其指向不变
命名格式为:类名 * const 指针变量名
Time t1(8, 8, 8) , t2; 定义对象
Time * const ptr; const位置在指针变量名前面,指定ptr是const指针变量
ptr = &t1 ; ptr指向对象t1,此后不能再改变指向
ptr = &t2; 错误,ptr不能改变指向
或 Time * const ptr = &t1; 指定ptr指向t1
注意:
指向对象的const指针变量的值不能改变,即始终指向同一个对象,但可以改变其所指向对象(t1)的值。
如果想将一个指针变量固定地与一个对象相联系(即该指针变量始终指向一个对象),可以将它指定为const指针变量。往往用const指针作函数的形参,目的是不允许在函数执行过程中改变指针变量的值,使其始终指向原来的对象。
(4)指向const变量的指针变量
命名格式:const 类型名 * 指针变量名
如果一个变量已被声明为const变量,只能用指向const变量的指针变量指向它,而不能用指向非const变量的指针变量去指向它。
const char c[ ] = "boy" ; 定义const型的char数组
const cahr * p1 ; 定义p1为指向const型的char变量的指针变量
p1 = c ; 合法,p1指向const变量(char数组的首元素)
char * p2 = c ; 不合法,p2不是指向const变量的指针变量
指向const变量的指针变量除了可以指向const变量外,还可以指向未被声明为const的变量,此时不能通过此指针变量改变该变量的值。
char c1 = 'a' ; 定义字符变量c1,它并未声明为const
const char * p ; 定义了一个指向const变量的指针变量p
p = &c1 ; 使p指向字符变量c1
*p = 'b' ; 非法,不能通过p改变变量c1的值
c1 = 'b' ; 合法,没有通过p访问c1,c1不是const变量
注意:
指向const变量的指针变量可以指向一个非const变量。这时可以通过指针变量访问该变量,但不能改变该变量的值。如果不是通过指针变量访问,则变量的值是可以改变的。
用指针变量作形参时形参和实参的对应关系
形参 | 实参 | 合法性 | 改变指针所指向的变量的值 |
指向非const型变量的指针 | 非const变量的地址 | 合法 | 可以 |
指向非const型变量的指针 | const变量的地址 | 非法 | / |
指向const型变量的指针 | const变量的地址 | 合法 | 不可以 |
指向const型变量的指针 | 非const变量的地址 | 合法 | 不可以 |
(5)指向const对象的指针变量
命名格式:const 类名 * 指针变量名
如果一个对象已被声明为const对象,只能用指向const对象的指针变量指向它,而不能用指向非const型对象的指针变量去指向它。
如果定义了一个指向const对象的指针变量,并使它指向一个非const的对象,则其指向的对象是不能通过该指针变量来改变的。
Time t1 (8, 8, 8) ; 定义Time类对象t1,它是非const型对象
const Time * p = &t1; 定义p是指向const对象的指针变量,并指向t1
t1.hour = 18; 合法,t1不是const变量
(* p) . hour = 18; 非法,不能通过指针变量改变t1的值
注意:
Time * const p; 指向对象的const指针变量
const Time * p; 指向const对象的指针变量
指向const对象的指针最常用于函数的形参,目的是在保护形参指针所指向的对象,使它在函数执行过程中不被修改。
当希望在调用函数时对象的值不被修改,就应当把形参定义为指向const对象的指针变量,同时用对象的地址作实参(对象可以是const或非const),如果要求该对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应把它定义为const型。
如果定义了一个指向const对象的指针变量,是不能通过它改变所指向的对象的值,但是指针变量本身的值是可以改变的。
const Time * p = &t1; 定义指向const对象的指针变量p,并指向对象t1
p = &t2; p改为指向t2,合法
(6)对象的const引用
如果形参为变量的引用,实参为变量名,则在调用函数进行虚实结合实,把实参变量的地址传给形参引用,这样引用就指向实参变量。对象的引用也是与此类似的。
void fun (const Time &t) 这样在函数中就不能改变t所代表的实参的值,注意,不是不能改变“引用t”的指向,而是t所指向的变量的值。
const指针与const引用经常作为函数参数,这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。
(7)const型数据的小结
形式 | 含义 |
Time const t | t是const对象,其值在任何情况下都不能改变 |
void Time :: fun() const | fun是Time类中的const成员函数,可以引用,但不能修改本类中的数据成员 |
Time * const p | p是指向Time类对象的const指针变量,p的值(p的指向)不能改变 |
const Time * p |
p是指向Time类const对象的指针变量,p指向的类对象的值不能通过p来改变 |
const Time &t1 = t | t1是Time类对象t的引用,二者指向同一存储空间,t的值不能改变 |