第三章 类
第三节 inline,const,mutable, this, static
1. 在类定义中实现成员函数inline
-
类内的成员函数实现也叫做类内的成员函数定义
-
直接在类的定义中实现的函数直接被系统认为是内联函数(inline),但是能不能够成功,取决于编译器本身
#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H
class Time {
private:
// 私有成员变量不能在外部直接用成员变量名使用
// 可以自己的成员函数调用
int Millisecond;//毫秒
void initMillTime(int mls);
public:
int Hour;
int Minute;
int Second;
// 成员函数
void initTime(int tmphour, int tmpmin, int tmpsec);
public:
//构造函数
Time(int tmphour, int tmpmin, int tmpsec = 22);
//不加参数
Time();
//单参数的构造函数
explicit Time(int tmphour);
//直接在类中定义的函数直接被系统认为是内联函数
void addHour(int temphour){
Hour += temphour;
}
};
#endif //LESSION_PART_TWO_TIME_H
2. 成员函数末尾的const
-
const 是一个常量的概念,在成员函数末尾增加const,不但要在成员函数声明中增加const,也要在成员函数定义中增加const
-
作用: 告诉系统这个成员函数不会修改该对象里任何成员的值,也就是说这个成员函数不会修改Time类中任何成员变量,这种函数也叫做常量成员函数
-
Time.h中
void addHour(int temphour) const;
- Time.cpp
//这种方式会报错,因为不允许修改对象中的成员变量,也就不能修改Hour的值
void Time::addHour(int temphour) const {
Hour = temphour+1;
}
一个const类对象的范例
- Time.h
//
// Created by felaim on 2020/5/26.
//
#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H
class Time {
public:
int Hour;
int Minute;
int Second;
int Millisecond;//毫秒
// 成员函数
void initTime(int tmphour, int tmpmin, int tmpsec);
public:
//构造函数
Time(int tmphour, int tmpmin, int tmpsec = 22);
//不加参数
Time();
//单参数的构造函数
explicit Time(int tmphour);
void initMillTime(int mls);
void addHour(int temphour) const;
void noone() {}
void noonec() const {}
};
#endif //LESSION_PART_TWO_TIME_H
- Time.cpp
//
// Created by felaim on 2020/5/26.
//
#include "Time.h"
// 成员函数initTime的实现
// ::叫做作用域运算符,表示initTime属于Time类
void Time::initTime(int tmphour, int tmpmin, int tmpsec) {
//成员函数中可以直接使用成员变量名
// 哪个对象调用的成员函数,这些成员变量就属于对应的对象
Hour = tmphour;
Minute = tmpmin;
Second = tmpsec;
initMillTime(25);
}
void Time::initMillTime(int mls) {
Millisecond = mls; //成员函数访问成员变量
}
Time::Time(int tmphour, int tmpmin, int tmpsec)
: 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(int tmphour) {
Hour = tmphour;
Minute = 59;
Second = 59;
}
void Time::addHour(int temphour) const {
}
- main.cpp
#include <iostream>
#include "Time.h"
using namespace std;
int main() {
// 添加explict仍然可行
Time myTime{12, 12, 3};
cout << "myTime: " << myTime.Hour << ":" << myTime.Minute << ":" << myTime.Second << endl;
// 定义const对象
const Time 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();
return 0;
}
- const 成员函数不管是const对象还是非const对象都可以调用const成员函数,而非const成员函数,不能被const对象调用,只能被非const对象调用
3. mutable
-
mutable:不稳定,容易改变的意思,与const意思相反,mutable是为了突破const的限制
-
用mutable来修饰一个成员变量,一个成员变量一旦被mutable修饰了,这个成员变量永远处于可以被修改状态,即便是在const结尾的成员函数中
-
一个简单例子,先混个脸熟
//成员变量中添加public对象
mutable int testVal;
//成员函数中添加
void noonec() 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.
//
#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H
class Time {
public:
int Hour;
int Minute;
int Second;
int Millisecond;//毫秒
mutable int testVal;
// 成员函数
void initTime(int tmphour, int tmpmin, int tmpsec);
public:
// 返回对象自己
Time &addHour(int temphour);
Time &addMin(int Minute);
public:
//构造函数
Time(int tmphour, int tmpmin, int tmpsec = 22);
//不加参数
Time();
//单参数的构造函数
explicit Time(int tmphour);
void initMillTime(int mls);
void noone() {}
void noonec() const {
testVal++;
}
};
#endif //LESSION_PART_TWO_TIME_H
- Time.cpp(添加代码)
// 返回对象自己
Time &Time::addHour(int temphour) {
Hour += temphour;//在系统看来等价与 this->Hour =+ temphour
return *this;
}
//编译器内部操作, 添加了一个内部指针
//Time & Time::addHour(Time *this, int temphour) {}
//如果形参和成员变量名相同,需要添加this->来进行区分
Time &Time::addMin(int Minute) {
this->Minute += Minute;
return *this;
}
- main.cpp
#include <iostream>
#include "Time.h"
using namespace std;
int main() {
Time mytime;
cout << "mytime " << mytime.Hour << " : " << mytime.Minute << endl;
// 如果能返回自己,就可以进行连调
mytime.addHour(3).addMin(4);
cout << "mytime " << mytime.Hour << " : " << mytime.Minute << endl;
return 0;
}
5. static成员变量
-
属于整个类的成员变量,这种成员变量就是static成员变量
-
特点: 不属于某个对象,属于整个类,一旦在某个对象中修改了这个成员变量的值,在其他对象中直接能够看到修改的结果
-
这种成员变量只有一个副本,对于这种成员变量的引用,我们用的是类名::成员变量名
-
成员函数前面也可以加static,构成静态成员函数,属于整个类的成员函数,我们用类名::成员函数
如何定义静态成员变量?
- 在某个.cpp源文件开头定义这个静态成员变量,这样就能够保证在调用任何函数之前这个静态成员变量已经被成功初始化
(此时在分配内存)
代码范例
- Time.h
//
// Created by felaim on 2020/5/26.
//
#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H
class Time {
public:
int Hour;
int Minute;
int Second;
int Millisecond;//毫秒
mutable int testVal;
//声明成员变量,还没有被分配内存,所以不能在这里初始化
// 静态成员变量
static int mystatic;
public:
// 返回对象自己
Time &addHour(int temphour);
Time &addMin(int Minute);
public:
//构造函数
Time(int tmphour, int tmpmin, int tmpsec = 22);
//不加参数
Time();
//单参数的构造函数
explicit Time(int tmphour);
void initTime(int tmphour, int tmpmin, int tmpsec);
void initMillTime(int mls);
void noone() {}
void noonec() const {
testVal++;
}
// 静态成员函数
static void mstafunc(int testValue);
};
#endif //LESSION_PART_TWO_TIME_H
- Time.cpp
//
// Created by felaim on 2020/5/26.
//
#include <iostream>
#include "Time.h"
// 静态成员变量定义(分配内存),定义的时候不需要使用static
// 可以不给初值,系统默认给0
int Time::mystatic = 15;
void Time::initTime(int tmphour, int tmpmin, int tmpsec) {
Hour = tmphour;
Minute = tmpmin;
Second = tmpsec;
initMillTime(25);
}
void Time::initMillTime(int mls) {
Millisecond = mls; //成员函数访问成员变量
}
Time::Time(int tmphour, int tmpmin, int tmpsec)
: Hour(tmphour), Minute(tmpmin), Second(tmpsec), Millisecond(0) {}
Time::Time() {
Hour = 0;
Minute = 0;
Second = 0;
}
Time::Time(int tmphour) {
Hour = tmphour;
Minute = 59;
Second = 59;
}
// 返回对象自己
Time &Time::addHour(int temphour) {
Hour += temphour;//在系统看来等价与 this->Hour =+ temphour
return *this;
}
//编译器内部操作, 添加了一个内部指针
//Time & Time::addHour(Time *this, int temphour) {}
//如果形参和成员变量名相同,需要添加this->来进行区分
Time &Time::addMin(int Minute) {
this->Minute += Minute;
return *this;
}
//静态成员函数中修改对象的成员变量
void Time::mstafunc(int testValue) {
mystatic = testValue;
}
- main.cpp
#include <iostream>
#include "Time.h"
using namespace std;
int main() {
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;
return 0;
}