const对象
const关键字能够修饰对象,修饰的对象为只读对象,它的成员变量不允许被改变,但这只是编译阶段的概念,运行时无效,可以使用指针修改成员变量。
既然有const对象,那么必然也存在const成员函数,但是它有什么特性呢?首先const对象只能调用const成员函数,const成员函数中也只能调用const成员函数,const成员函数中不能直接改写成员变量的值。
const成员函数定义和普通成员函数的区别只在于const成员函数在参数列表之后,函数体之前有一个const关键字,注意一点,类中的函数声明与实际函数定义中都必须带const关键字。
我们可以自行尝试定义一个const对象,然后改变其成员变量的值,但是编译肯定会报错,因为一个只读变量是不能作为左值的;也可以调用一个普通的成员函数,结果发现编译也是错的,因为const对象只能调用const成员函数;在const成员函数中调用一个普通成员函数或者修改成员变量的值依旧是错的,因为const成员函数只能调用const成员函数,它也不允许直接修改const对象的成员变量。最后说一下,在类的拷贝构造函数中是不能调用类其他的成员函数的,因为拷贝构造函数将一个对象指明为了const,所以它只能调用const成员函数,但是它却能调用普通成员变量(包括私有成员变量)这是为什么呢?不是说私有成员变量只是在自己的成员函数中才能被访问吗?那么下面讲解另一个话题---this指针。
this指针
先看一个例子:
class Test
{
int mi;
public:
int mj;
Test(int i);
Test(const Test& t);
int getMi();
void print();
};
Test::Test(int i)
{
mi = i;
}
Test::Test(const Test& t)
{
mi = t.mi;//能编译通过,为什么?后面讲解
}
int Test::getMi()
{
return mi;
}
void Test::print()
{
printf("this = %p\n", this);
}
首先问一个问题,成员函数和成员变量都是隶属于具体对象的吗?
每一个对象都拥有自己的一套成员变量,但是所有对象共享同一套成员函数。
从程序运行角度上看,对象由数据和函数构成,数据可以位于堆、栈、全局数据区,函数只能位于代码段,代码段是只读的,当编译器将代码段编译成可执行文件时程序在运行期间是不可以改变的。数据可以动态的创建,但是函数是不能动态的改变的,由于函数的这种特性导致所有对象共用同一套成员函数。但是在一个程序中,不同的对象调用同一个成员函数时是由什么来区分开的?区别于普通函数,成员函数有一个隐藏的参数,叫做this指针,用来指代当前调用成员函数的对象。
前面创建的类里面添加了this指针的打印语句,当我们调用下面程序段时:
Test t1(1);
Test t2(2);
Test t3(3);
printf("t1.getMi() = %d\n", t1.getMi());
printf("&t1 = %p\n", &t1);
t1.print();
printf("t2.getMi() = %d\n", t2.getMi());
printf("&t2 = %p\n", &t2);
t2.print();
printf("t3.getMi() = %d\n", t3.getMi());
printf("&t3 = %p\n", &t3);
t3.print();
看看打印结果:
t1.getMi() = 1
&t1 = 0060FEF8
this = 0060FEF8
t2.getMi() = 2
&t2 = 0060FEF0
this = 0060FEF0
t3.getMi() = 3
&t3 = 0060FEE8
this = 0060FEE8
发现打印出来的this指针值和对象的地址是一样的,表示this指针就是用来指向当前调用成员函数的对象本身。
所以前面拷贝构造函数即使是const类型的对象但是由于所有对象拥有自己的一套成员变量,那么它就能在函数体内使用自己的那一套的成员变量。