C++ ———— 3(友元+运算符重载)
一、限制构造
构造函数在类的非public区域,称为
限制构造
函数,如果一个类的构造函数是限制构造,那么就不能通过该类直接实例化对象
,只能通过类的静态成员函数
或者友元函数
去实例化对象。
二、友元
友元:
可以打破类的权限限制,利用友元可以访问private和protected权限的成员 类实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是某些情况下,需要频繁读写类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递、类型检查和安全性检查等都需要时间开销肖,而影响程序的运行效率。
友元的关键字:
friend友元:
不是类的成员,没有this指针
分类:
- 友元函数
- 友元类
- 友元成员函数
1.友元函数
一个函数fun是一个类A的友元,我们就称fun是A的友元函数
声明位置:
友元函数可以在类内的任何位置声明,也可以在类外声明,不属于类
格式:
friend void func(Demo &obj) //友元函数例子 { cout << obj.val << endl; }
2. 友元类
一个类A是另一个类B的友元类,那么此时A类的所有成员都可以访问类B
3.友元成员函数
有一个类A它里面有个成员函数fun是类B的友元,此时我们就称fun是友元成员函数
三、运算符重载
函数可以重载,运算符也可以重载
一般形式:
返回值类型 operator运算符(参数) { //函数体 }
不能被重载的运算符:
?: //三目运算符 sizeof //去大小运算符 :: //名字空间符 '.' '.*' //对象指针等 , //逗号一般不建议重载,即使要重载,也必须是类类型
运算符重载可以使用的方法:
- 成员函数重载
- 友元函数重载
- 普通函数重载
练习:
重载 ! 判断顺序表是否为空
/*=============================================== * 文件名称:eg3_chongzai.cpp * 创 建 者:青木莲华 * 创建日期:2025年08月28日 * 描 述: ================================================*/ #include <iostream> using namespace std; class A { public: A(int max) { p = new int[max]; this-> max = max; len = 0; } ~A() { if(p != nullptr) { delete p; p = nullptr; } len = 0; max = 0; } void insert(int num) { if(len+1 >= max) return; else { p[len] = num; len++; } } bool operator!() { return len == 0 ? true : false; } private: int *p; int len; int max; }; int main() { A a(10); !a ? cout << "obj is null" << endl : cout << "obj not null" << endl; a.insert(10); !a ? cout << "obj is null" << endl : cout << "obj not null" << endl; return 0; }
四、作业
运算符重载——重载顺序表类的 += 、+ 等运算符
源码
/*=============================================== * 文件名称:List.cpp * 创 建 者:青木莲华 * 创建日期:2025年08月28日 * 描 述:完善顺序表类,实现=、+=的重载。 ================================================*/ #include <iostream> using namespace std; class List { public: //无参构造 List(){} //有参构造 List(int size) { this->size = size; p = new int[size]; index = 0; } //拷贝函数 List(List &list) { cout << "copy" << endl; //1.拷贝最大元素个数 size = list.size; //2.拷贝当前元素个数 index = list.index; //开辟新数组空间 p = new int[size]; //逐个拷贝数组 for(int i = 0 ; i < index ; i++) { p[i] = list.p[i]; } } //插入新元素 void insert(int num) { //1.判满 if(index+1 >= size) return; //2.插入元素 p[index] = num; //3.修改index index++; } //遍历函数 void show() { for(int i = 0 ; i < index ; i++) { cout << p[i] << " "; } cout << endl; } //'+'运算符重载 List operator+(const List &list) { //1.实例化一个中间对象 this + list List temp(this->size + list.size); temp.index = index + list.index; //2.拷贝 this 数组的所有元素 for(int i = 0 ; i < index ; i++) temp.p[i] = p[i]; //3.拷贝 list 数组的所有元素 for(int i = 0 ; i < list.index ; i++) temp.p[index + i] = list.p[i]; //4.返回中间对象 return temp; } //'+='运算符重载 += obj void operator+=(const List &list) { //1.定义临时数组 int *temp = new int[size + list.size]; //2.拷贝数组内容 this for(int i = 0 ; i < index ; i++) temp[i] = p[i]; for(int i = 0 ; i < list.index ; i++) temp[index + i] = list.p[i]; //3.拷贝index index += list.index; //4.拷贝size size += list.size; //5.删除旧数组 delete[] p; //6.改变p指向到temp; p = temp; } //'+='重载 += 常量 void operator+=(const int num) { //判满 if(index+1 >= size) return; p[index] = num; index++; } private: int *p; //顺序表指针,指向数组 int size; //顺序表最大元素个数 int index; //顺序表当前元素个数 }; int main(int argc, char *argv[]) { cout << "-------a------" << endl; List a(10); a.insert(11); a.insert(22); a.insert(33); a.insert(44); a.show(); cout << "-------b------" << endl; List b(10); b.insert(55); b.insert(66); b.insert(77); b.insert(88); b.show(); cout << "------c = a + b------" << endl; List c; c = a + b; c.show(); cout << "------a += b------" << endl; a += b; a.show(); cout << "------a += 常数------" << endl; a += 311; a.show(); return 0; }
运行截图