一、const
1. 修饰成员函数
用const修饰成员函数时,const修饰 this 指针指向的内存区域,成员函数体内不可以修改本类中的任何普通成员变量,当成员变量类型符前用 mutable 修饰时例外。
int myFun(void) const {} // const 修饰的是成员函数
// 函数内不能修改 类中:
#include <iostream>
class Data {
private:
int data;
mutable int num; // 添加可修改标志
public:
// 遍历 成员的函数 不会去修改成员的值
void myPrintData() const {
std::cout << this->data << std::endl;
// data = 1; // 错误 , const 不能修改
num = 200;
}
public:
Data() {
std::cout << "无参构造" << std::endl;
}
Data(int data) {
this->data = data;
std::cout << "有参构造" << std::endl;
}
Data(const Data &ob) {
this->data = ob.data;
std::cout << "拷贝构造" << std::endl;
}
~Data() {
std::cout << "析构函数" << std::endl;
}
};
int main()
{
Data ob1(100);
ob1.myPrintData();
return 0;
} 2. 修饰对象称为常对象
const int num = 10; 不会开辟空间,num 会被放入符号表中。
int main()
{
// 常对象
const Data ob1(200);
// 常对象只能调用const修饰的函数,遍历成员数据
ob1.myPrintData();
// 访问没有const修饰的函数是不允许的
return 0;
} 二、友元函数
c++允许友元访问私有数据。
1. 语法:
friend关键字只出现在声明处 其他类、类成员函数、全局函数都可声明为友元 友元函数
不是类的成员,不带this指针 友元函数可访问对象任意成员属性,包括私有属性。
2. 普通全局函数作为类的友元
#include <iostream>
class Room {
private:
friend void goodGayVisit(Room &room);
// 将goodGayVisit作为类的友元函数
// 可以访问类中的所有数据 但是 不是 类的成员
private:
std::string bedRoom; //卧室
public:
std::string sittingRoom; // 客厅
public:
Room(): bedRoom("卧室"), sittingRoom("客厅") {
}
};
// 友元函数在类外定义,且非对象的函数,没有this指针
void goodGayVisit(Room &room) {
std::cout << "访问" << room.sittingRoom << std::endl;
std::cout << "访问" << room.bedRoom << std::endl; // 可以访问私有属性
}
int main()
{
Room myRoom;
goodGayVisit(myRoom);
return 0;
} 3. 类作为另一个类的友元
- 类的某个成员函数作为另一个类的友元
- 类整体作为另一个类的友元
这里碰到一个问题,如果分文件写,会造成循环依赖的问题。
在设计类的时候要充分考虑头文件引入的问题,尽量避免多次引入相同的头文件,以及相互引入(相互会出现错误)。
4. 一个电视机类
封装电视机和遥控器类:
#include <iostream>
using namespace std;
class TV {
private:
// 添加一个遥控器
friend class Remote;
private:
enum { ON, OFF };
enum { minVol, maxVol=100 };
enum { minChannel=1, maxChannel=255 };
private:
int state; // 电视状态,开机/关机
int volume; // 电视机音量
int channel; // 电视频道
public:
// 构造函数
TV(): state(OFF), volume(minVol), channel(minChannel) {}
~TV() {};
public:
// 开关
void switchButton() {
state = state == ON ? OFF : ON;
}
// 音量
// 音量+
void volumeUp() {
if (volume >= maxVol) {
return ;
}
++volume;
}
// 音量-
void volumeDown() {
if (volume <= minVol) {
return ;
}
--volume;
}
// 频道
// 频道+
void channelUp() {
if (channel >= maxChannel) {
return ;
}
++channel;
}
// 频道-
void channelDown() {
if (channel <= minChannel) {
return ;
}
--channel;
}
// 显示电视机状态
std::string whatState() {
return state == ON ? "开机" : "关机";
}
// 显示音量
int whatVolume() {
return volume;
}
// 显示频道
int whatChannel() {
return channel;
}
// 显示所有状态
void showTVState() {
std::cout << "电视机状态: "
<< whatState() << std::endl;
std::cout << "电视机音量: "
<< whatVolume() << std::endl;
std::cout << "电视机频道: "
<< whatChannel() << std::endl;
}
};
// Remote 类 遥控器
/**
该类作为TV的友元类
*/
class Remote {
private:
TV *tv;
public:
Remote(TV *pTv): tv(pTv) {}
public:
// 音量
// 音量+
void volumeUp() {
tv->volumeUp();
}
// 音量-
void volumeDown() {
tv->volumeDown();
}
// 频道
// 频道+
void channelUp() {
tv->channelUp();
}
// 频道-
void channelDown() {
tv->channelDown();
}
// 电视开关
void switchButton() {
tv->switchButton();
}
// 设置频道
void setChannel(int num) {
// 频道是否有效
if (num >= TV::minChannel
&& num <= TV::maxChannel) {
tv->channel = num;
}
}
void showTVState() {
tv->showTVState();
}
};
// 测试1
void test01() {
TV tv;
tv.switchButton(); // 开机
tv.volumeDown(); // 0
tv.volumeUp(); // 1
tv.volumeUp(); // 2
tv.volumeUp(); // 3
tv.volumeDown(); //2
tv.channelDown(); // 1
tv.channelDown(); // 1
tv.channelUp(); // 2
tv.channelUp(); //3
tv.showTVState();
}
// 测试2
void test02() {
TV tv;
Remote remote(&tv);
remote.switchButton(); // 开机
remote.volumeDown(); // 0
remote.volumeUp(); // 1
remote.volumeUp(); // 2
remote.volumeUp(); // 3
remote.volumeDown(); //2
remote.channelDown(); // 1
remote.channelDown(); // 1
remote.channelUp(); // 2
remote.channelUp(); //3
remote.showTVState();
remote.setChannel(22);
remote.showTVState();
}
int main()
{
test01();
test02();
return 0;
} 关于枚举:
枚举是一个常量,在编译的时候会放入常量区,可以直接使用类名:枚举变量调用。

京公网安备 11010502036488号