一步一步学习C++(类)之成员函数的特性

使用内联函数应注意的事项内联函数具有一般函数的特性,它与一般函数所不同之处公在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。在使用内联函数时,应注意如下几点:

1.一个函数可以自已调用自已,称为递归调用(后面讲到),含有递归调用的函数不能设置为inline;

2.使用了复杂流程控制语句:循环语句和switch语句,无法设置为inline;

3.由于inline增加体积的特性,所以建议inline函数内的代码应很短小。最好不超过5行。

4.inline仅做为一种“请求”,特定的情况下,编译器将不理会inline关键字,而强制让函数成为普通函数。出现这种情况,编译器会给出警告消息。

5.在你调用一个内联函数之前,这个函数一定要在之前有声明或已定义为inline,如果在前面声明为普通函数,而在调用代码后面才定义为一个inline函数,程序可以通过编译,但该函数没有实现inline。

总结为几句话

1.在内联函数内不允许用循环语句和开关语句。2.内联函数的定义必须出现在内联函数第一次被调用之前。

只要声明为内联,编译器就不把它编译成一次函数调用,而只是类似于把函数的代码拷贝到被调用的地方,而且这完全是编译器私下里完成的,原来的访问权限等问题丝毫不受影响。这不是两全齐美了吗:在保证代码的面向对象性和结构化不受损失的条件下,程序的效率也没有损失。

Class MyClass { public: inline int GetState(); private: int m_iState; }int inline MyClass::GetState() { return m_iState; } 内联函数还有另外一种写法,就是直接写在类中,此时,不必使用“inline”关键字。

class MyClass { public: int GetState(){return m_iState;} private: int m_iState; }; 内联函数只是一种编译机制,用上面两种形式声明的函数仅仅是建议编译器进行内联,而编译器是否内联不一定。正如前面所说,函数调用的开销只是对小的函数不可忽略,对于重量级的函数还是可以忽略的,而且在绝大多数的场合,函数调用才是人间正道,才是解决问题的最佳。所以大多数编译器并不把带有循环、递归等或者代码比较多的函数进行内联编译,有的甚至不允许声明成内联的。

二.静态成员

类是类型而并非数据对象,每个类的对象都是该类数据成员的拷贝。然而,在有的时候,需要类的所有对象在类的范围内共享某个数据。声明为static的类成员便能在类的范围内中共享,称之为静态成员。因此,静态成员的提出是为了解决数据共享问题。

static主要有三个作用:

(1)局部静态变量

(2)外部静态变量/函数

(3)静态数据成员/成员函数

由于全局变量不属于类的成员,它的访问权限是完成开放的,因此,既不安全,又影响了重用性。

而静态成员具有上述问题的双重属性,不但数据可以得到封装,又可为所有的对象所共享。

静态数据成员是类中所有对象所共享的成员,而不是某个对象的成员。

静态数据成员的另一个优势是可以节省内存,对多个对象来说,静态数据成员只存储一处,为所有的对象所共用。

静态数据成员的值对每个对象都是一样的,但它的值可以更新。只要对静态数据成员的值更新一次,可保证所有对象存取更新后的相同值,这样可提高时间效率。

2.1静态成员的初始化在类的体外进行,而值得注意的是前面不加关键字static的意义在于避免与一般静态变量或对象相混淆。

class MyClass { public: int GetState(){return m_iState;} private: int m_iState; static int a;//定义} ;<span style="color:#ff0000;"></span>int MyClass::a = 0;//初始化2.2 静态数据成员被 类 的所有对象所共享,,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员

// StaticForClass.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"class MyClass { public: int GetState(){return m_iState;} static int a;//定义private: int m_iState; }; int MyClass::a = 0;//初始化class DerivedClass:public MyClass{};int _tmain(int argc, _TCHAR* argv[]){MyClass A;DerivedClass B;printf("%d\n",A.a);A.a++;printf("%d\n",B.a);getchar();return 0;}<span style="color:#ff0000;"></span>三、静态成员函数3.1静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存

// StaticForClass.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"class MyClass { public: static int GetState();void print();static int a;//定义private: int m_iState;}; int MyClass::a = 0;//初始化int MyClass::GetState()//静态函数的调用{return a;//return m_iState;/* error C2597: 对非静态成员“MyClass::m_iState”的非法引用*/}void MyClass::print(){printf("%d",a);}class DerivedClass:public MyClass{};int _tmain(int argc, _TCHAR* argv[]){#if 0MyClass A;DerivedClass B;printf("%d\n",A.a);A.a++;printf("%d\n",B.a);#endifint (*pf1)() = &MyClass::GetState;//普通的函数指针 //int (MyClass::*pf2)() = &MyClass::GetState;/*error C2440: “初始化”: 无法从“int (__cdecl *)(void)”转换为“int (__thiscall MyClass::* )(void)”*/void (MyClass::*pf3)() = &MyClass::print;//普通的函数指针getchar();return 0;}

走过的路成为背后的风景,不能回头不能停留,若此刻停留,

一步一步学习C++(类)之成员函数的特性

相关文章:

你感兴趣的文章:

标签云: