友元就是friend修饰函数或者类,友元只是单纯的提供一个场所赋予对象具有无视权限功能(不是说直接就可以访问另一个数据)
友元函数- 友元函数不属于类,就是一个普通函数,类外实现不需要类名限定
- 以另一个类的成员函数当做友元函数,需要注意写法
#include友元类// 正常友元函数的写法 using namespace std; class YXC { public: YXC(string name = "默认",int age = 12):name(name),age(age){} // 友元函数 friend void print(YXC& object); void printYXC() { cout << name << "t" << age << endl; } private: string name; int age; }; // 类外实现不需要类名限定 void print(YXC& object) { YXC* p = new YXC; p->name = "无视权限"; p->age = 123; p->printYXC(); cout << object.name << "t" << object.age << endl; } // 不正常的写法: 以另一个类的成员函数当做友元函数 class YXC_B{ public: YXC_B(int b = 1234) :YXC_B_value(b){} void printYXC_B(); private: int YXC_B_value; }; class YXC_A { friend void YXC_B::printYXC_B(); // 不受A的权限限定 public: YXC_A(int a = 122):YXC_A_value{a}{} private: int YXC_A_value; }; void YXC_B::printYXC_B() { YXC_A aobject; cout << aobject.YXC_A_value << endl; cout << "b中的函数" << endl; } int main() { YXC yxc; // cout << yxc.name << endl; // 错误 没有权限,不可访问 print(yxc); YXC_B bObject; YXC_A aObject; bObject.printYXC_B(); // 类 B的函数成功打印了A中的私有属性的值为122 return 0; }
- 在另一个类中用friend修饰声明的类,称之为友元类
#includeC++运算符重载using namespace std; class Boy_YXC { friend class Girl_YXC; // 友元类 public: Boy_YXC(string name,int age):name(name),age(age){} private: void printBoy_YXC() { cout << name << "t" << age << endl; } string name; int age; }; class Girl_YXC { public: Girl_YXC(string name,int age):boy_yxc(name,age){} void printInfo() { cout << boy_yxc.name << "t" << boy_yxc.age << endl;// 无视权限 Boy_YXC* pB = new Boy_YXC("new", 18); pB->printBoy_YXC(); // 无视权限 cout << pB->age << "t" << pB->name << endl; } private: Boy_YXC boy_yxc; }; // 互为友元类 class Test { friend class Data; public: void printTest(); private: void test() { cout << "测试权限专用函数" << endl; } }; class Data { friend class Test; public: void printData() { Test tObject; tObject.test(); } private: void data() { cout << "测试权限专用函数" << endl; } }; void Test::printTest() { Data dObject; dObject.data(); cout << "printTest" << endl; } int main() { Test test; test.printTest(); Data data; data.printData(); return 0; }
声明是运算符重载? 运算符重载是赋予自定义数据能被运算符直接操作,运算符重载实质伤就是函数调用
运算符重载函数的长相:
- 函数返回值类型,这个运算符最终运算结果的类型 YXC a , YXC b; YXC c = a + b ;(YXC)
- 函数名: operator加上运算符组成函数名 operator+ 这个整体函数名
- 函数参数: 看运算符需要几个参数去运算,传几个参数
- 友元重载:参数个数是等于操作数
- 类重载:参数个数是等于操作数-1
- 参数类型:操作数的类型决定
- 函数体:写你想要的运算(不成文规定:不能违背运算符本来含义)
#include特殊重载#include using namespace std; class YXC { public: YXC(){} YXC(string name,int age) :name(name),age(age){} void printYXC() { cout << name << "t" << age << endl; } // 友元重载 yxc + xchuan friend YXC operator+(YXC& oobject1, YXC& object2); // 类成员函数重载: 减法重载 YXC operator-(YXC& object); private: string name; int age; }; // 局部变量的地址和引用 YXC operator+(YXC& object1, YXC& object2) { // return YXC(object1.name, object2.age + object2.age); YXC yxc; yxc.name = object1.name; yxc.age = object1.age + object2.age; return yxc; } YXC YXC::operator-(YXC& object) { return YXC(this->name, this->age - object.age); } int main() { // 友元重载 YXC yxc("易小川", 18); YXC xchuan("小川", 20); // vs中重载的运算符是绿色 YXC result = yxc + xchuan; // 运算符重载隐式调用 // yxc + xchuan解析过程: operator+(yxc,xchuan); string str1 = "dsd"; string str2 = "sdsd"; cout << (str1 > str2) << endl; YXC result2 = operator+(yxc, xchuan); // 显示隐式 result2.printYXC(); YXC temp1 = result2 - yxc; // 隐式调用: 解析为: result2.operator-(yxc); temp1.printYXC(); YXC temp2 = yxc - result2; temp2.printYXC(); return 0; }
- = () -> [] 只能重载为类的成员函数
- . .* ?: :: 不能被重载
- 重载必须要存在一个自定义类型
- 一个重载习惯: 单目运算类重载,双目采用友元重载
- ++ – 重载
- 前置和后置一个处理,后置通常会增加一个无用int参数作为标记
- 输入输出重载
- 流对象的类型
- cout: ostream —> 输出流对象
- cin: istream —> 输入流对象
- 友元重载
- 尽量保存用引用类型
- 流对象的类型
- 文本重载
- 文本重载是后缀重载
- 对象隐式转换
#includeC++运算符重载综合案例#include #include using namespace std; class YXC { public: YXC(){} YXC(string name,int age) :name(name),age(age){} void printYXC() { cout << name << "t" << age << endl; } YXC operator++(int) // 后置++的标记 { return YXC(this->name, this->age++); } YXC operator++() { this->age++; return (*this); } friend istream& operator>>(istream& in, YXC& object); friend ostream& operator<<(ostream& out, YXC& object); private: string name; int age; }; istream& operator>>(istream& in, YXC& object) // cin >> temp; { cout << "请输出YXC的数据: "; in >> object.name >> object.age; return in; } ostream& operator<<(ostream& out, YXC& object) { cout << "name\tage" << endl; out << object.name << "t" << object.age << endl; return out; } // 后缀尽量用下划线 unsigned long long operator""_h(unsigned long long hour) { return hour * 60 * 60; } unsigned long long operator""_m(unsigned long long min) { return min * 60; } unsigned long long operator""_s(unsigned long long sec) { return sec; } // 对象的隐式转换 class YXC_super { public: YXC_super(string name,int age) :name(name),age(age){} // operator 要转的类型() // 对象的隐式转换 operator int() { return age; //返回值 } operator double() { return (double)age; } private: string name; int age; }; int main() { // No.1 前置和后置重载 YXC yxc("易小川", 18); YXC xchuan = yxc++; xchuan.printYXC(); yxc.printYXC(); YXC xxchuan = ++yxc; yxc.printYXC(); xxchuan.printYXC(); // No.2 流重载 YXC temp; cin >> temp; cout << temp; // No.3 后缀重载 int count = 1_h + 39_m + 30_s; cout << count << endl; // No.4 对象的隐式转换 YXC_super ycc("易川川", 22); int age = ycc; cout << age << endl; double age2 = ycc; cout << age2 << endl; return 0; }
// 1.简单封装一个数据类型 // 2.封装函数包装器: 把函数封装成一个对象 // 3.封装一下智能指针,实现内存自动申请和释放 #includeC++默认存在的函数#include #include using namespace std; // No.1 简单封装一个数据 class Int { public: Int(int num = 0) :m_num(num){} int& data() // string : data() c_str() { return m_num; } int toint() { return m_num; } string to_string() { return ::to_string(m_num); // 区分一下,C++中有一个to_string } int operator()() { return m_num; } public: // 算术 Int operator+(const Int& value) { return Int(this->m_num + value.m_num); } Int operator-(const Int& value) { return Int(this->m_num - value.m_num); } Int operator/(const Int& value) { return Int(this->m_num / value.m_num); } Int operator*(const Int& value) { return Int(this->m_num * value.m_num); } Int operator%(const Int& value) { return Int(this->m_num % value.m_num); } public: // 条件运算符重载 bool operator==(const Int& value) { return this->m_num == value.m_num; } bool operator!=(const Int& value) { return this->m_num != value.m_num; } bool operator>(const Int& value) { return this->m_num > value.m_num; } bool operator<(const Int& value) { return this->m_num < value.m_num; } bool operator>=(const Int& value) { return this->m_num >= value.m_num; } public: // 赋值运算符 Int& operator=(const Int& value) { this->m_num = value.m_num; return *this; } Int& operator+=(const Int& value) { this->m_num += value.m_num; return *this; } public: // 单目运算符 Int operator-() { return Int(-this->m_num); } Int* operator&() { return this; } public: friend ostream& operator<<(ostream& out, const Int& object) { out << object.m_num; return out; } friend istream& operator>>(istream& in, Int& object) { in >> object.m_num; return in; } private: int m_num; }; void test_my_int() { Int number(123); cout << number() << endl; Int temp; cin >> temp; cout << temp << endl; cout << (number == temp) << endl; } // No.2 封装函数包装器 class Func { using PF = void(*)(); public: Func(PF pf):pf(pf){} void operator()() { pf(); } Func operator=(PF& pf){ this->pf = pf; } private: PF pf; }; void print() { cout << "函数调用" << endl; } void printYXC() { cout << "我叫易小川" << endl; } void test_func() { // 函数包装器: 把函数指针包装成为对象 Func object(print); object(); // 在通过对象调用函数 Func object2 = print; object2(); object2 = printYXC; object2(); } // No.3 智能指针 class Auto_ptr_int { public: Auto_ptr_int(int* ptr) :ptr(ptr){} ~Auto_ptr_int() { delete ptr; } // 取值运算 int operator*() { return ptr[0]; // return *ptr } int*& get() { return ptr; } private: int* ptr; }; void test_ptr() { Auto_ptr_int p(new int(100)); cout << *p << endl; cout << *(p.get()) << endl; } int main() { test_my_int(); test_func(); test_ptr(); return 0; }
#include#include using namespace std; class YXC { public: YXC() = default; ~YXC() = default; YXC(const YXC& object) = default; YXC& operator=(const YXC& object) = default; // 1.默认构造函数 // 2.默认析构函数 // 3.默认拷贝构造函数 // 4.默认的赋值重载 void printYXC() { cout << "name:"" << this->name <<""" << "tage:" << this->age; } private: string name; int age; }; // 重载中的特殊情况 // 对象加常量的情况 class Test { public: Test(int num) :num(num){} void printData() { cout << num << endl; } // 正常人处理方法 // friend Test operator+(Test test,int data)_ // { // return Test(test.num + data); // } // friend Test operator+(int data,Test test) //{ // return Test(test.num + data); //} Test operator+(Test test1) { return Test(this->num + test1.num); } private: int num; }; int main() { YXC yxc; YXC result = yxc; YXC temp; temp = yxc; temp.printYXC(); Test object(1); object.printData(); // 不正常的重载智能用友元方式,才可以让下面都正确 // 友元重载解析:operator+(1,object); Test object1=1 Test res = object + 1; // 友元重载解析: operator+(object,1); res.printData(); // Test res = 1 + object;// 类成员函数重载会报错 // res2.printData(); return 0; }



