- 博客主页:https://loewen.blog.csdn.net
- 欢迎点赞 收藏 ⭐留言 如有错误敬请指正!
- 本文由 丶布布原创,首发于 CSDN,转载注明出处
- 现在的付出,都会是一种沉淀,只为让你成为更好的人✨
假设我们不在头文件中声明、源文件中定义函数了,而是全部放在头文件中来实现:
class Time
{
public:
explicit Time(int tmphour);
int Hour;
public:
void addHour(int tempHour)
{
Hour += tempHour;
}
};
这种直接在类的定义中实现的函数,会被系统当做内联函数inline
来处理,其他相关的知识点可以参考我们之前的讲解。
成员函数后面增加一个const
的限定词后也被称为常量成员函数,其特性与用法如下:
特性:
1.不但要在成员函数的声明后增加const,也要在成员函数的定义中增加const
2.非成员函数不允许使用const修饰符
3.const成员函数既能被const类型对象调用也能被非const类型对象调用
作用:
const成员函数被限定:不能在函数中修改关于类的任何状态,包括其各种成员变量的值
举例:
//.h
class Time
{
public:
explicit Time(int tmphour);
explicit Time();
int Hour;
public:
void addHour(int tempHour) const;
};
//.cpp
void addHour(int tempHour) const
{
Hour = tempHour; //报错:表达式必须是可修改的左值(因为const定义的成员函数,其内的成员变量值不能被修改)
}
此外,const
成员函数也是个万人迷,既能被const
类型对象调用也能被非const
类型对象调用;非const
成员函数只能被非const
类型对象调用。
public:
void addHour(int tempHour) const;
void addMinute(int tempMinute);
问题:
如何修改const
修饰的常量成员函数中的成员变量?
前面我们说过常量成员函数中的成员变量不可以进行修改,这里有人会想了,那我直接取消常量成员函数后面的const
修饰,将其变成普通成员函数,是不是就可以正常修改其内的成员变量了。没错,这样是可以修改了,但是我们不要忘了:
const
成员函数既能被const
类型对象调用也能被非const
类型对象调用const
成员函数(普通成员函数)只能被非const
类型对象调用这就导致一个问题,就是如果之前代码中是使用const
类型对象调用的常量成员函数,这时将常量成员函数变成普通成员函数后,我们也必须将调用其的const
类型对象改为非const
类型对象后才能正常调用修改后的普通成员函数。将原本const
修饰的类对象取消掉,这违背了程序设计的初衷——不想让这个类对象修改成员变量的值。
定义:
为了解决上述的问题,我们引入了mutable
的概念来突破const
的限制,mutable
(不稳定,容易改变的意思),const
的反义词。
用mutable
修饰的成员变量,表示这个成员变量永远处于可以被修改的状态,即便是在const
结尾的常量成员函数中。
举例:
class Time
{
public:
mutable int Hour;
public:
void addHour(int tempHour) const;
};
void Time::addHour(int tempHour) const
{
Hour = tempHour; //因为Hour是被mutable修饰的,这里即使是在常量成员函数addHour中,仍然可以被修改。
}
class Time
{
public:
int Hour = 50;
public:
Time &addHour(int tempHour);
};
Time &Time::addHour(int tempHour)
{
Hour += tempHour;
return *this; //把对象自己给返回去了
}
int main()
{
Time myTime;
myTime.addHour(2);
}
类Time
对象myTime
的地址:0x001df720
结论: 说明this
是一个指向自身类对象(myTime
)的指针。
return *this
返回的是当前对象的克隆或者本身(若返回类型为Time
,则是克隆;若返回类型为Time&
,则是本身。本文举例是后者)。return this
返回当前对象的地址(指向当前对象的指针)如何理解这个this?
当我们在程序中调用成员函数/成员变量时,编译器负责把这个对象的地址(&myTime
)传递给成员函数中一个隐藏的this
形参。
即:
//我们写的:T
ime &Time::addHour(int tempHour){}
//实际上的
Time &Time::addHour(Time *this, int tempHour){}
Time myTime;
//我们写的:
myTime.addHour(2);
//实际上的
myTime.addHour(&myTime, 2); //调用时,编译器会把myTime的地址传递给成员函数隐藏的`this`形参
这也解释了一个问题:为什么在成员函数中,不需要调用就可以直接使用成员变量?
Time &Time::addHour(int tempHour)
{
//程序员角度:
Hour += tempHour; //成员变量Hour
//系统的角度:
this->Hour += tempHour;
}
因为在系统角度看来,任何对类成员(Hour
)的直接访问,都被系统看做是通过this
做隐式调用的(this->Hour
)。
this的相关特性:
this
指针只能在成员函数中使用,静态函数或全局函数等是不存在this
指针的。const
对象的const
指针。Time
,那么this
的实际定义是Time *const this
,即this
指针只能指向当前类对象,不能在指向其他类的对象(const后置)。const
成员函数中(void Time::addHour(int tempHour) const;
), this是一个指向const
对象的const
指针。Time
,那么this
的实际定义是const Time *const this
,不但this
不能在指向其他类对象,而且this
指向的自身类对象的成员变量值也不能更改。参考我的另一篇文章:[C++] static静态成员变量/函数的用法
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |