前一篇文章中说到,内联成员函数的定义有两种方式,一种是在类体内部直接定义,第二种是在类体外定义。下面是代码:
第一种定义方式:
class Test { public: void add(int a, int b) //类体中直接定义时为内联函数。 { return a+b; } };第二种定义方式为:
inline Test::add(int a, int b) //在类体外定义 { return a+b; }内联函数的目的主要是为了提高程序执行的效率,编译器在编译的时候会将代码直接嵌入到调用的地方,从而减少了函数调用的开销,如果不用内联函数,直接嵌入代码,则代码体积将增大,这实际上是以空间换取时间的策略。所以内联函数的代码必须短小,内联函数对编译器而言仅仅是一个提示,另外,如果函数中含有switch for 等语句,则编译器不会将其解读为内联。
下面讲讲成员函数的重载
成员函数的重载是有条件的,首先必须具有相同的作用域,且参数不同(可以是参数类型不同,参数个数不同,参数顺序不同),函数名相同。这样的成员函数才构成重载。下面是重载的例子:
class Test { public: void Init(); void Init(int x); void Init(int x, int y); void Init(int x, int y, int z); //void Init(int x=0, int y= 0, int z= 0 ); //与void Init();函数产生了二义性,编译器无法区分 };在上面这个例子中,定义了多个Init函数,由于他们的参数不同,所以构成重载,但是成员函数的重载需要注意的是,对于带有缺省值参数的成员函数的重载需要避免二义性,如上述代码中的注释行。它与不带参数的成员函数Init()就产生了二义性,编译器对此无法区分,因此会报错。
类与结构体(struct 与 class)
在C中的结构体struct其实与C++中的class有点类似的,它们都可以将各种数据结构与方法封闭在一个容器中。唯一的区别在于:在未指定访问权限时,struct默认是public的,而class默认是private的。如下:
class Test { int x; //actually x is private. };
struct Test { int x; //x is public };在class中可以定义函数,其实在C++中的struct内也可以定义函数,只不过他们的访问权限均为public的,如果class内定义的所有数据成员与成员函数均为public,则与struct定义没有任何区别。下面这段代码非常简单,可以看出二者的区别。
struct Test2 { int x_; int y_; int z_; void Init(int x, int y, int z) { x_ = x; y_ = y; z_ = z; } }; class Test3 { int x_; int y_; int z_; void Init(int x, int y, int z ) { x_ = x; y_ = y; z_ = z; } }; int main() { Test2 t; //在C++中,struct也是一个类,不需要加上struct t.Init(10,20,30); Test2 t2 = {10,20,30}; //C中结构体的初始化,这是允许的 Test3 t3; t3.Init(10,20,30);//Error,Init在t3中是private的,外部无法直接访问 Test3 t4 = {10,20,30}; //Error,在class中,数据成员为private,不能像struct那样初始化。 }
关于this指针
为了搞清this指针,需要了解一个背景:在C++中,成员函数的代码对所有对象而言是共享的,而每个对象的数据成员空间各自独立,那么当每个对象都调用成员函数时,成员函数如何区别它应该操作哪一个对象的数据呢?换句话说,成员函数怎么知道它要操作的是调用它的对象的数据成员?这主要是C++编译器来完成,C++编译器在每次成员函数调用时,在第一个参数会增加一个对象的指针,以告诉成员函数它要操作的是哪个对象的数据。编译器传递的这个指针是不可见的,是隐含的。
我们程序代码中调用成员函数是这样的:
Test t1; t1.Init(10,20,30);
而编译器处理后,是这样的:
Test t1; t1.Init(&t1, 10, 20, 30);这个被编译器传递进去的指针就是this指针了,这样在成员函数代码被执行时就指向了t1的数据成员。当然,我们在成员函数定义时可以将这个this指针省略。