成员函数末尾的const
- 在成员函数末尾增加一个
const
是告诉系统,这个成员函数不会修改对象里面任何成员变量的值等。也就是说,这个成员函数不会修改类对象的任何状态。这种在末尾缀了一个const
的成员函数称之为“常量成员函数”。 const
成员函数可以被const
对象和非const
对象调用。而 非const
成员函数只能非const
对象调用。
对于成员函数声明和实现分开的情况下,不但要在函数声明中增加const,也要在函数实现中增加
const
。
普通函数(非成员函数)末尾是不能增加const
的。
mutable
mutable
修饰符(关键字)来修饰一个成员变量,就表示这个成员变量的值处于可变的状态,即使是在一个以const
结尾的成员函数中。
举例说明:
下面代码写在.h头文件time
类中
public:
//const mutable
mutable int a = 0;
void add() const //写在类中,是函数的定义
{
//本来在const成员函数中是不能修改变量值的,但该变量是mutable修饰的,意思是可变的
a += 4;
}
在main主文件中
time my2time;
const time c_mytime; // 定义一个const对象
my2time.add();
c_mytime.add(); // 可见 const成员函数可以被const和非const对象调用
c_mytime.unsigtime(0,0,0); //编译不通过,const对象不能调用非const成员函数unsigtime
返回自身对象的引用——this
this
用在成员函数中是一个隐藏起来的函数参数,表示的是指向本对象的指针。那么*this
表示该指针指向的对象就是本对象。换句话说,*this
表示调用这个成员函数的那个对象。this
是系统保留字,所以参数名、变量名都不能起名叫this
。this
本身是一个指针常量,总是指向这个对象本身,不可以让this
在指向其他地方。
this
指针只能用在成员函数中使用,全局函数和静态函数等都不能使用this
指针。- 在普通成员函数中,
this
是指向非const
对象的指针常量。- 在
const
成员函数中,this
指针是一个指向const
对象的const
指针。即常指针常量。
在.h头文件time
类中加入以下声明
public:
time& rtnhour(int temh);
在.cpp文件中实现
time& time::rtnhour(int temh)
{
Hour += temh; // 如果传递近来的形参也叫Hour,则成员变量可以写成this.Hour以示区别(this.Hour += Hour)
return *this;
}
static成员
static
成员变量(静态成员变量),其特点是不属于某个对象,而是属于整个类。这种成员变量可以通过对象名来修改值,也可以通过类名来修改值,但一旦修改其值,则在其他该类对象中也能够直接看到修改后的结果。- 引用方法:类名::静态成员变量名
- 参考静态成员变量,则成员函数也可以在其前加
static
关键字,增加了这种关键字的成员函数同样就不隶属与某个对象,而是隶属于整个类。当然static
成员函数只能操作和类相关的成员变量(static
成员变量),不能操作和对象相关的成员变量。 - 引用方法:类名::静态成员函数名(…)
仔细看如下代码
在.h头文件time
类中加入以下声明
public:
static int myM;
static void stmi(int m);
静态成员变量和普通成员变量不同,普通成员变量在定义一个类对象时,就已经分配内存了,那静态成员变量什么时候分配内存呢?
其实,上面的代码只是声明,还未分配内存,若要使用,必须定义这个静态成员变量,也就是给静态成员变量分配内存。一般在某一个.cpp文件的开头定义这个静态成员变量。
在main文件开头定义静态成员变量
#include <iostream>
#include"time.h"
//static成员
int time::myM = 7; // 不给初值,系统就会默认为0,定义时无需static
int main()
...
time tsta;
std::cout << time::myM << std::endl;
std::cout << tsta.myM << std::endl; // 也可以用“对象名.成员变量”的方式来访问
...
在.cpp文件中实现静态成员函数
void time::stmi(int m) // 静态成员函数在实现时前面不需要再加static关键字
{
//不能引用Hour等对象相关的成员变量
myM = m;
}
在main文件中调用
time::stmi(70);
std::cout << time::myM << std::endl;
tsta.stmi(77); // 也可以用“对象名.成员函数名”引用
std::cout << time::myM << std::endl;
附注工程程序:
time.h
#ifndef _TIME_H
#define _TIME_H
class time
{
public:
unsigned Hour;
unsigned Min;
unsigned Sec;
private:
unsigned MillTime;
public:
void unsigtime(unsigned H,unsigned M,unsigned S);
private:
void unsigmilltime(unsigned Mill);
public:
unsigned Year;
unsigned Month;
time(unsigned Y, unsigned M=11);
//time(unsigned Y, unsigned M);
time();
//const mutable
mutable int a = 0;
void add() const //写在类中,是函数的定义
{
//本来在const成员函数中是不能修改变量值的,但该变量是mutable修饰的,意思是可变的
a += 4;
}
//this
time& rtnhour(int temh);
time& rtnMin(int temm);
//static成员
static int myM;
static void stmi(int m);
};
#endif // !_TIME_H
time.cpp
#include"time.h"
//这两个冒号叫 作用域运算符,表示unsigtime函数属于time类。避免多个类中相同的函数无法分别
void time::unsigtime(unsigned H, unsigned M, unsigned S)
{
Hour = H;
Min = M;
Sec = S;
unsigmilltime(7);
}
void time::unsigmilltime(unsigned Mill)
{
MillTime = Mill;
}
/*time::time(unsigned Y, unsigned M) //构造函数,系统自动调用进行初始化
{
Year = Y;
Month = M;
}*/
time::time(unsigned Y, unsigned M) //构造函数
:Year(Y), Month(M) //初始化列表
{
}
time::time() //构造函数
{
Year = 20; //赋值
Month = 12;
}
//this
time& time::rtnhour(int temh)
{
//temh += 77;
Hour += temh;
return *this;
}
time& time::rtnMin(int temm)
{
//temh += 77;
Min += temm;
return *this;
}
//static成员
void time::stmi(int m)
{
//不能引用Hour等对象相关的成员变量
myM = m;
}
main.cpp
#include <iostream>
#include"time.h"
//static成员
int time::myM = 7;
int main()
{
//time mytime = time(2020,11); //初始化
//time mytime = time{2020,11};
time mytime(2020,12);
//带有默认参数
//time mytime; //可以定义不同的构造函数,最后调用形式不一样
//time mytime{};
mytime.unsigtime(12, 33, 47);
std::cout << mytime.Hour << std::endl;
std::cout << mytime.Min << std::endl;
std::cout << mytime.Sec << std::endl;
std::cout << mytime.Year << std::endl;
std::cout << mytime.Month << std::endl;
time my2time = mytime;
std::cout << my2time.Year << std::endl;
std::cout << my2time.Month << std::endl;
//const mutable
std::cout << "-----------const mutable-----------" << std::endl;
my2time.add();
std::cout << my2time.a << std::endl;
const time c_mytime;
c_mytime.add();
// c_mytime.unsigtime(0,0,0); //编译不通过,const对象不能调用非const成员函数
std::cout << c_mytime.a << std::endl;
//this
std::cout << "-----------this-----------" << std::endl;
time time_this(12,12);
time_this.unsigtime(1,0,1);
time_this.rtnhour(7).rtnMin(33);
std::cout << time_this.Hour << std::endl;
std::cout << time_this.Min << std::endl;
//static成员
std::cout << "-----------static成员-----------" << std::endl;
//int time::myM = 7; 此行需写到.cpp文档的最上面
time tsta;
std::cout << time::myM << std::endl;
std::cout << tsta.myM << std::endl;
time::stmi(70);
std::cout << time::myM << std::endl;
tsta.stmi(77);
std::cout << time::myM << std::endl;
}