第三章 类
第三节 inline,const,mutable, this, static
1. 在类定义中实现成员函数inline
类内的成员函数实现也叫做类内的成员函数定义
直接在类的定义中实现的函数直接被系统认为是内联函数(inline),但是能不能够成功,取决于编译器本身
#ifndefLESSION_PART_TWO_TIME_H#defineLESSION_PART_TWO_TIME_Hclass Time{private:// 私有成员变量不能在外部直接用成员变量名使用// 可以自己的成员函数调用intMillisecond;//毫秒voidinitMillTime(intmls);public:intHour;intMinute;intSecond;// 成员函数voidinitTime(inttmphour,inttmpmin,inttmpsec);public://构造函数Time(inttmphour,inttmpmin,inttmpsec=22);//不加参数Time();//单参数的构造函数explicitTime(inttmphour);//直接在类中定义的函数直接被系统认为是内联函数voidaddHour(inttemphour){Hour+=temphour;}};#endif//LESSION_PART_TWO_TIME_H2. 成员函数末尾的const
const 是一个常量的概念,在成员函数末尾增加const,不但要在成员函数声明中增加const,也要在成员函数定义中增加const
作用: 告诉系统这个成员函数不会修改该对象里任何成员的值,也就是说这个成员函数不会修改Time类中任何成员变量,这种函数也叫做常量成员函数
Time.h中
voidaddHour(inttemphour)const;- Time.cpp
//这种方式会报错,因为不允许修改对象中的成员变量,也就不能修改Hour的值voidTime::addHour(inttemphour)const{Hour=temphour+1;}一个const类对象的范例
- Time.h
//// Created by felaim on 2020/5/26.//#ifndefLESSION_PART_TWO_TIME_H#defineLESSION_PART_TWO_TIME_Hclass Time{public:intHour;intMinute;intSecond;intMillisecond;//毫秒// 成员函数voidinitTime(inttmphour,inttmpmin,inttmpsec);public://构造函数Time(inttmphour,inttmpmin,inttmpsec=22);//不加参数Time();//单参数的构造函数explicitTime(inttmphour);voidinitMillTime(intmls);voidaddHour(inttemphour)const;voidnoone(){}voidnoonec()const{}};#endif//LESSION_PART_TWO_TIME_H- Time.cpp
//// Created by felaim on 2020/5/26.//#include"Time.h"// 成员函数initTime的实现// ::叫做作用域运算符,表示initTime属于Time类voidTime::initTime(inttmphour,inttmpmin,inttmpsec){//成员函数中可以直接使用成员变量名// 哪个对象调用的成员函数,这些成员变量就属于对应的对象Hour=tmphour;Minute=tmpmin;Second=tmpsec;initMillTime(25);}voidTime::initMillTime(intmls){Millisecond=mls;//成员函数访问成员变量}Time::Time(inttmphour,inttmpmin,inttmpsec):Hour(tmphour),Minute(tmpmin),Second(tmpsec),Millisecond(0){}// 构造函数的实现//Time::Time(int tmphour, int tmpmin, int tmpsec) {// Hour = tmphour;// Minute = tmpmin;// Second = tmpsec;//// initMillTime(0);//}Time::Time(){Hour=12;Minute=59;Second=59;}Time::Time(inttmphour){Hour=tmphour;Minute=59;Second=59;}voidTime::addHour(inttemphour)const{}- main.cpp
#include<iostream>#include"Time.h"using namespace std;intmain(){// 添加explict仍然可行Time myTime{12,12,3};cout<<"myTime: "<<myTime.Hour<<":"<<myTime.Minute<<":"<<myTime.Second<<endl;// 定义const对象constTime cmyTime;//报错,不能调用修改对象的成员函数//cmyTime.initMillTime(2);// 也不能使用普通函数,因为noone()没有别被声明成const//cmyTime.noone();//可以使用const 成员函数cmyTime.noonec();//initMillTime只能被非const对象调用myTime.initMillTime(3);cout<<"myTime.Millisecond : "<<myTime.Millisecond<<endl;myTime.noone();//非const对象也可以调用const的成员函数myTime.noonec();return0;}- const 成员函数不管是const对象还是非const对象都可以调用const成员函数,而非const成员函数,不能被const对象调用,只能被非const对象调用
3. mutable
mutable:不稳定,容易改变的意思,与const意思相反,mutable是为了突破const的限制
用mutable来修饰一个成员变量,一个成员变量一旦被mutable修饰了,这个成员变量永远处于可以被修改状态,即便是在const结尾的成员函数中
一个简单例子,先混个脸熟
//成员变量中添加public对象mutableinttestVal;//成员函数中添加voidnoonec()const{testVal++;}// 主程序中进行测试// 发现无论是不是const对象,都可以对mutable定义的testVal值进行修改myTime.testVal=100;cout<<"myTime.testVal: "<<myTime.testVal<<endl;cmyTime.testVal=200;cout<<"cmyTime.testVal: "<<cmyTime.testVal<<endl;4. 返回自身对象的引用,this
如何理解this?
调用成员函数的时候,编译器负责把对象的地址(&mytime)传递给这个成员函数中的一个隐藏的this形参在系统角度看来,任何对类成员的直接访问,都被看作是通过this做隐式调用的
this指针只能在成员函数中使用,全局函数以及静态函数都不能使用this指针
在普通成员函数中,this是指向非const对象的const指针,(类型为Time,就是Time *const this),this只能指向当前这个对象,不能指向其他对象
在const成员函数中,this指针是一个指向const对象的const指针,(类型为Time,就是const Time * const this)
代码修改
- time.h
//// Created by felaim on 2020/5/26.//#ifndefLESSION_PART_TWO_TIME_H#defineLESSION_PART_TWO_TIME_Hclass Time{public:intHour;intMinute;intSecond;intMillisecond;//毫秒mutableinttestVal;// 成员函数voidinitTime(inttmphour,inttmpmin,inttmpsec);public:// 返回对象自己Time&addHour(inttemphour);Time&addMin(intMinute);public://构造函数Time(inttmphour,inttmpmin,inttmpsec=22);//不加参数Time();//单参数的构造函数explicitTime(inttmphour);voidinitMillTime(intmls);voidnoone(){}voidnoonec()const{testVal++;}};#endif//LESSION_PART_TWO_TIME_H- Time.cpp(添加代码)
// 返回对象自己Time&Time::addHour(inttemphour){Hour+=temphour;//在系统看来等价与 this->Hour =+ temphourreturn*this;}//编译器内部操作, 添加了一个内部指针//Time & Time::addHour(Time *this, int temphour) {}//如果形参和成员变量名相同,需要添加this->来进行区分Time&Time::addMin(intMinute){this->Minute+=Minute;return*this;}- main.cpp
#include<iostream>#include"Time.h"using namespace std;intmain(){Time mytime;cout<<"mytime "<<mytime.Hour<<" : "<<mytime.Minute<<endl;// 如果能返回自己,就可以进行连调mytime.addHour(3).addMin(4);cout<<"mytime "<<mytime.Hour<<" : "<<mytime.Minute<<endl;return0;}5. static成员变量
属于整个类的成员变量,这种成员变量就是static成员变量
特点: 不属于某个对象,属于整个类,一旦在某个对象中修改了这个成员变量的值,在其他对象中直接能够看到修改的结果
这种成员变量只有一个副本,对于这种成员变量的引用,我们用的是类名::成员变量名
成员函数前面也可以加static,构成静态成员函数,属于整个类的成员函数,我们用类名::成员函数
如何定义静态成员变量?
- 在某个.cpp源文件开头定义这个静态成员变量,这样就能够保证在调用任何函数之前这个静态成员变量已经被成功初始化
(此时在分配内存)
代码范例
- Time.h
//// Created by felaim on 2020/5/26.//#ifndefLESSION_PART_TWO_TIME_H#defineLESSION_PART_TWO_TIME_Hclass Time{public:intHour;intMinute;intSecond;intMillisecond;//毫秒mutableinttestVal;//声明成员变量,还没有被分配内存,所以不能在这里初始化// 静态成员变量staticintmystatic;public:// 返回对象自己Time&addHour(inttemphour);Time&addMin(intMinute);public://构造函数Time(inttmphour,inttmpmin,inttmpsec=22);//不加参数Time();//单参数的构造函数explicitTime(inttmphour);voidinitTime(inttmphour,inttmpmin,inttmpsec);voidinitMillTime(intmls);voidnoone(){}voidnoonec()const{testVal++;}// 静态成员函数staticvoidmstafunc(inttestValue);};#endif//LESSION_PART_TWO_TIME_H- Time.cpp
//// Created by felaim on 2020/5/26.//#include<iostream>#include"Time.h"// 静态成员变量定义(分配内存),定义的时候不需要使用static// 可以不给初值,系统默认给0intTime::mystatic=15;voidTime::initTime(inttmphour,inttmpmin,inttmpsec){Hour=tmphour;Minute=tmpmin;Second=tmpsec;initMillTime(25);}voidTime::initMillTime(intmls){Millisecond=mls;//成员函数访问成员变量}Time::Time(inttmphour,inttmpmin,inttmpsec):Hour(tmphour),Minute(tmpmin),Second(tmpsec),Millisecond(0){}Time::Time(){Hour=0;Minute=0;Second=0;}Time::Time(inttmphour){Hour=tmphour;Minute=59;Second=59;}// 返回对象自己Time&Time::addHour(inttemphour){Hour+=temphour;//在系统看来等价与 this->Hour =+ temphourreturn*this;}//编译器内部操作, 添加了一个内部指针//Time & Time::addHour(Time *this, int temphour) {}//如果形参和成员变量名相同,需要添加this->来进行区分Time&Time::addMin(intMinute){this->Minute+=Minute;return*this;}//静态成员函数中修改对象的成员变量voidTime::mstafunc(inttestValue){mystatic=testValue;}- main.cpp
#include<iostream>#include"Time.h"using namespace std;intmain(){Time mytime;mytime.Minute=15;Time mytime2;mytime2.Minute=30;cout<<"mytime.Minute: "<<mytime.Minute<<endl;cout<<"mytime2.Minute: "<<mytime2.Minute<<endl;cout<<"Time::mystatic: "<<Time::mystatic<<endl;cout<<"mytime.mystatic: "<<mytime.mystatic<<endl;mytime.mystatic=88;cout<<"mytime2.mystatic: "<<mytime2.mystatic<<endl;mytime2.mstafunc(199);cout<<"mytime.mystatic: "<<mytime.mystatic<<endl;return0;}