定义
函数的定义一般在类外面,也可以直接在类内部定义。
前者与普通函数不同的是,实现成员函数时要指明类的名称,具体形式为:
- 返回值类型 类名::函数成员名(参数表){函数体};
- 而后者一般为一些短小的函数(5行以内),也就是内联函数。
所属关系
各类函数中:构造函数、析构函数、拷贝初始化构造函数等是类的成员函数。
class A
{
public:
void B();
private:
int C();
protected:
bool D(int i);
};
//那么,B(),C(),D(int)都是A的成员函数
类的大小
成员函数不会影响类的结构体大小,类的大小只计算类内部的成员变量。
空类的字节大小为一个字节,因为类本身需要也需要一个字节来保证这个类能被声明和调用。
成员函数的作用域
类的成员函数想要定义在类的外部时,可以使用 ”函数的类型 类名 ::函数名“ 的方式
来进行类的外部定义。
注意,类的成员函数要定义在类的外部时,需要在类的内部声明这个函数才可以在外部定义。
//示例:
class A
{
private:
int a;
public:
int Add(int b);
}
int A:: Add(int b)
{
return a + b;
}
内联成员函数(inline)
内联函数推荐写在头文件中。
内联函数的重写原则:内联函数在声明时未使用 inline关键词,但是在定义时使用了 inline 关键词这个函数还是会被定义为内联函数。
class B
{
private:
int a;
public:
int Add(int b);
}
inline int B::Add(int b)
{
return a + b;
}
const 对象
const 修饰的对象不能修改其成员变量的值。const对象只能调用 const修饰过的成员函数。
const 原则
const对象不能以任何方式改变,这是const的原则,在这个基本的原则下,产生了一系列效应,比如 const对象只能调用const成员函数;
另外一个我们不注意的变化是,在const成员函数中,this指针也变成了const指针。
const 类型转换
//语法:
const_cast<类型>(变量);
Role user;
const_cast<Role*>(puser);
const_cast可以将一个const变量的常量属性去掉,
只有在极少数情况下需要用到const_cast
muteble
mutable声明的成员变量可以被const成员函数修改。
mutale关键字可以用于调试时的数量统计,因为被mutable修饰过的变量不会被const所影响。
#include <iostream>
class Role
{
public:
//TODO:成员函数的const修饰只能在函数的尾部修饰才会生效,如果声明在头部改变的是数据类型
inline int GetHp() const;
Role& SetHp(int newHp);
Role& SetMp(int newMp);
//TODO:const成员函数不能返回引用,如果一定要使用引用来返回值可以将函数的数据类型修饰
//为const来进行返回。
const int& GetMp() const;
int GetDamage();
int GetDamage()const;
int GetLv() const;
private:
int Hp;
int Mp;
int Damage;
int lv;
mutable int GetList;
//TODO:mutable修饰过的变量因为不会被const属性所影响,
//所以可以在所有的成员函数中调用并改变变量的值
};
void test(Role* p) {
p->SetHp(500);
}
int main()
{
const Role uesr;
Role monster;
const Role* puser{ &monster };
puser->GetHp();
//TODO:const修饰过的成员函数,未声明为const的对象同样可以调用
monster.GetHp();
//TODO:const的对象调用的就是const的成员函数
uesr.GetDamage();
//TODO:未使用const修饰的对象则调用未使用const修饰的成员函数
monster.GetDamage();
//TODO:下面俩种调用方式相同,都是讲变量的const属性去除。
test((Role*)(&uesr));
//这种方式是C语言的强制类型转换将const类型的对象转换成非const的对象
test(const_cast<Role*>(&uesr));
//这种方式是C++的去除const对象的常量属性的方式
}
inline int Role::GetHp() const
{
/*TODO:
const修饰过的成员函数内部不可以改变成员变量的值,
同时const修饰过的成员函数的this指针会变成const指针,同样不能修改成员变量的值
*/
return Hp;
}
Role& Role::SetHp(int newHp)
{
GetList++;
Mp = newHp;
return *this;
}
Role& Role::SetMp(int newMp)
{
GetList++;
Hp = newMp;
return *this;
}
const int& Role::GetMp() const
{
//如果没有使用const修饰函数返回值的数据类型,则返回的引用的值是可以被改变的。
//这样就违反了const原则,所以是不能被编译的。
GetList++;
return Mp;
}
//TODO:const也可以作为函数重载的条件之一
int Role::GetDamage() const
{
std::cout << "const GetDamage!\n";
GetList++;
return 0;
}
int Role::GetDamage()
{
std::cout << "GetDamage!\n";
GetList++;
return 0;
}
int Role::GetLv() const
{
//TODO:被mutable修饰过的变量可以被const成员函数修改
GetList++;
return lv;
}