1.常函数
常函数:类中的成员函数参数列表后面有const修饰时,称之为常函数,其主要作用是为了保护类中成员变量,限制修改。
特性:不能修改类中的非静态成员,但是可以查看。对于静态成员属性不但能查看,也能对其进行修改,因为静态成员不是属于对象的,并不在const的约束范围内。
常量对象:使用const修饰的对象(如:const CTest tst;)不能调用普通的成员函数,只能调用常函数。
#include<iostream>
using namespace std;
class CTest
{
public:
mutable int m_a; //方法一
const int m_b;
static int m_c;
CTest():m_a(2), m_b(3)
{
m_a = 1;
}
CTest(int a) :m_b(a),m_a(m_b)
{
cout << a << endl;
}
//常函数
void fun(/* const CTest* const this */)const
{
//方法二
/*int* p = (int*)&this->m_a;
*p = 10;
cout << m_a << endl;*/
m_a = 20;
m_c = 20;
cout << m_a << " " << m_b <<" "<<m_c << endl;
//fun1(/* CTest* const this */); //在常函数中不能直接调用普通的函数
fun2(); //在常函数中能直接调用静态函数
}
//普通函数
void fun1()
{
fun2();
fun();
}
//静态函数
static void fun2()
{
/* fun();
fun1();*/ //静态函数不能直接调用常函数和普通函数
}
};
int CTest::m_c = 10;
int main()
{
CTest tst;
tst.fun();
int* p = nullptr;
const int* p2 = p; //int* ->const int*,指针安全级别升级操作 合法
//p = p2; //const int* ->int* //error 指针安全级别降级操作 非法
return 0;
}
关于类中普通函数、静态函数、常函数:
1.普通函数可以调用静态函数和常函数;静态函数不能调用普通函数和常函数;常函数不能调用普通函数,但可以调用静态函数。
2.静态函数只能使用静态成员变量。
3.如果要在常函数中对类中普通成员变量赋值,可通过两种方法:法一:在变量前加mutable关键字;法二:通过指针改变。
2.类之间的横向关系(组合、依赖、关联和聚合)
组合(复合)
定义:它是一种"is a part of"的关系,部分与整体,包含与被包含。组合是一个类中包含另一个类对象。相比聚合,组合是一种强所属关系,组合关系的两个对象往往具有相同的生命周期,被组合的对象是在组合对象创建的同时或者创建之后创建,在组合对象销毁之前销毁。一般来说被组合对象不能脱离组合对象独立存在,整体不存在,部分一定不存在。
举例:人和手之间的关系,即手是人的一部分且不能脱离人独立存在
在C++语法中,通常在组合类中包含被组合类对象来实现组合关系
依赖
定义:它是一种"uses a"的关系。一个对象的某种行为依赖于另一个类对象,被依赖的对象视为完成某个功能的工具,并不持有对他的引用,只有完成某个功能的时候才会用到,而且是必不可少的。依赖之间是没有生命周期约束关系的。
举例:人用电脑编程,即电脑作为一个工具,其他的时候不需要,电脑也不可能作为人的属性而存在(非组合关系),人必须依赖于电脑才能完成编程这件事。
C++语法中,代码的表现形式为多种,通常将被依赖的对象作为另一类方法的参数的形式实现两个类之间的依赖关系
关联
定义:它是一种"has a"的关系。关联不是从属关系,而是平等关系,可以拥有对方,但不可占有对方。完成某个功能与被关联的对象有关,但可有可无,被关联的对象与关联对象无生命周期约束关系,被关联对象的生命周期由谁创建就由谁来维护。只要二者同意,可以随时解除关系或是进行关联,被关联的对象还可以再被别的对象关联,所以关联是可以共享的。
举例:人和朋友的关系,人要完成游戏这个功能,没有朋友可以自己玩游戏,如果交到朋友了就可以和朋友一起玩游戏。
C++语法中,通常在关联的类中定义被关联类对象的指针形式实现两个类之间的关联关系
聚合
定义:它是一种"owns a"的关系。多个被聚合的对象聚集起来形成一个大的整体,聚合的目的是为了统一进行管理同类型的对象,聚合是一种弱所属关系,被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系,相当于强版本的关联。
举例:一堆人组成一个家庭,进行统一管理完成玩游戏的功能。
C++语法中,通常在聚合类中定义被聚合对象指针的数组、链表等容器
接下来我们设计一个类图,方便之后写代码。
准备工作完成,下面我们开始用一下!
#include<iostream>
using namespace std;
class CHand {
public:
void Move() {
cout << "手不停地移动" << endl;
}
};
class CComputer {
public:
void Compile() {
cout << "编译程序..生成可执行文件" << endl;
}
};
class CFriend {
public:
void Play() {
cout << "我的朋友玩的挺好" << endl;
}
};
class CPeople {
public:
CHand m_hand;
CFriend* m_pFri;
CPeople() :m_pFri(nullptr) { }
public:
void clap() {
m_hand.Move();
cout << "发出了雷鸣般的掌声" << endl;
}
void code(CComputer* pComp) {
if (!pComp) return;
m_hand.Move();
cout << "敲出一行行的代码" << endl;
pComp->Compile();
cout << "运行可执行程序" << endl;
}
void playLoL() {
if (m_pFri) {
m_pFri->Play();
cout << "我和朋友玩的非常高兴" << endl;
} else {
cout << "我只能自己孤独的玩耍了" << endl;
}
}
void eat() {
cout << "人在吃" << endl;
}
};
class CFamily {
public:
CPeople* arr[10];
CFamily() :arr{0} {
arr[0] = new CPeople;
arr[1] = new CPeople;
arr[2] = new CPeople;
}
~CFamily() {
//delete[]arr;
for (CPeople* peo : arr) {
if (peo) delete peo;
}
}
void AllPeopleEat() {
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
if (arr[i]) {
cout << "第 " << i << " :";
arr[i]->eat();
}
}
}
};
int main() {
{ //组合
CPeople peo;
peo.clap();
}
{ //依赖
CComputer comp;
CPeople peo;
peo.code(&comp);
}
{ //关联
CPeople peo;
peo.playLoL(); //自己玩
CFriend fri;
peo.m_pFri = &fri;
peo.playLoL();
}
{ //聚合
CFamily fam;
fam.AllPeopleEat();
}
return 0;
}
输出结果:
over!