千家信息网

C++友元与运算符重载怎么应用

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要讲解了"C++友元与运算符重载怎么应用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C++友元与运算符重载怎么应用"吧!友元生活中你的家有
千家信息网最后更新 2026年10月31日C++友元与运算符重载怎么应用

这篇文章主要讲解了"C++友元与运算符重载怎么应用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C++友元与运算符重载怎么应用"吧!

友元

生活中你的家有客厅(Public),有你的卧室(Private),客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的好闺蜜好基友进去。

在程序里,有些私有属性也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。

友元的目的就是让一个函数或者类访问另一个类中私有成员。

友元的关键字为: friend

友元的三种实现:

  • 全局函数做友元

  • 类做友元

  • 成员函数做友元

1 全局函数做友元

class Building{        //告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容        friend void goodGay(Building * building);public:        Building()        {                this->m_SittingRoom = "客厅";                this->m_BedRoom = "卧室";        }public:        string m_SittingRoom; //客厅private:        string m_BedRoom; //卧室};void goodGay(Building * building){        cout << "好基友正在访问: " << building->m_SittingRoom << endl;        cout << "好基友正在访问: " << building->m_BedRoom << endl;}void test01(){        Building b;        goodGay(&b);}int main(){        test01();        system("pause");        return 0;}

2 类做友元

class Building;class goodGay{public:        goodGay();        void visit();private:        Building *building;};class Building{        //告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容        friend class goodGay;public:        Building();public:        string m_SittingRoom; //客厅private:        string m_BedRoom;//卧室};Building::Building(){        this->m_SittingRoom = "客厅";        this->m_BedRoom = "卧室";}goodGay::goodGay(){        building = new Building;}void goodGay::visit(){        cout << "好基友正在访问" << building->m_SittingRoom << endl;        cout << "好基友正在访问" << building->m_BedRoom << endl;}void test01(){        goodGay gg;        gg.visit();}int main(){        test01();        system("pause");        return 0;}

3 成员函数做友元

class Building;class goodGay{public:        goodGay();        void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容        void visit2(); private:        Building *building;};class Building{        //告诉编译器  goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容        friend void goodGay::visit();public:        Building();public:        string m_SittingRoom; //客厅private:        string m_BedRoom;//卧室};Building::Building(){        this->m_SittingRoom = "客厅";        this->m_BedRoom = "卧室";}goodGay::goodGay(){        building = new Building;}void goodGay::visit(){        cout << "好基友正在访问" << building->m_SittingRoom << endl;        cout << "好基友正在访问" << building->m_BedRoom << endl;}void goodGay::visit2(){        cout << "好基友正在访问" << building->m_SittingRoom << endl;        //cout << "好基友正在访问" << building->m_BedRoom << endl;}void test01(){        goodGay  gg;        gg.visit();}int main(){        test01();        system("pause");        return 0;}

运算符重载

运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

1 加号运算符重载

作用:实现两个自定义数据类型相加的运算

class Person {public:        Person() {};        Person(int a, int b)        {                this->m_A = a;                this->m_B = b;        }        //成员函数实现 + 号运算符重载        Person operator+(const Person& p) {                Person temp;                temp.m_A = this->m_A + p.m_A;                temp.m_B = this->m_B + p.m_B;                return temp;        }public:        int m_A;        int m_B;};//全局函数实现 + 号运算符重载//Person operator+(const Person& p1, const Person& p2) {//      Person temp(0, 0);//      temp.m_A = p1.m_A + p2.m_A;//      temp.m_B = p1.m_B + p2.m_B;//      return temp;//}//运算符重载 可以发生函数重载 Person operator+(const Person& p2, int val)  {        Person temp;        temp.m_A = p2.m_A + val;        temp.m_B = p2.m_B + val;        return temp;}void test() {        Person p1(10, 10);        Person p2(20, 20);        //成员函数方式        Person p3 = p2 + p1;  //相当于 p2.operaor+(p1)        cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;        Person p4 = p3 + 10; //相当于 operator+(p3,10)        cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;}int main() {        test();        system("pause");        return 0;}

总结1:对于内置的数据类型的表达式的的运算符是不可能改变的

总结2:不要滥用运算符重载

2 左移运算符重载

作用:可以输出自定义数据类型

class Person {        friend ostream& operator<<(ostream& out, Person& p);public:        Person(int a, int b)        {                this->m_A = a;                this->m_B = b;        }        //成员函数 实现不了  p << cout 不是我们想要的效果        //void operator<<(Person& p){        //}private:        int m_A;        int m_B;};//全局函数实现左移重载//ostream对象只能有一个ostream& operator<<(ostream& out, Person& p) {        out << "a:" << p.m_A << " b:" << p.m_B;        return out;}void test() {        Person p1(10, 20);        cout << p1 << "hello world" << endl; //链式编程}int main() {        test();        system("pause");        return 0;}

总结:重载左移运算符配合友元可以实现输出自定义数据类型

3 递增运算符重载

作用: 通过重载递增运算符,实现自己的整型数据

class MyInteger {        friend ostream& operator<<(ostream& out, MyInteger myint);public:        MyInteger() {                m_Num = 0;        }        //前置++        MyInteger& operator++() {                //先++                m_Num++;                //再返回                return *this;        }        //后置++        MyInteger operator++(int) {                //先返回                MyInteger temp = *this; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;                m_Num++;                return temp;        }private:        int m_Num;};ostream& operator<<(ostream& out, MyInteger myint) {        out << myint.m_Num;        return out;}//前置++ 先++ 再返回void test01() {        MyInteger myInt;        cout << ++myInt << endl;        cout << myInt << endl;}//后置++ 先返回 再++void test02() {        MyInteger myInt;        cout << myInt++ << endl;        cout << myInt << endl;}int main() {        test01();        //test02();        system("pause");        return 0;}

总结: 前置递增返回引用,后置递增返回值

4 赋值运算符重载

c++编译器至少给一个类添加4个函数

  • 默认构造函数(无参,函数体为空)

  • 默认析构函数(无参,函数体为空)

  • 默认拷贝构造函数,对属性进行值拷贝

  • 赋值运算符 operator=, 对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

示例:

class Person{public:        Person(int age)        {                //将年龄数据开辟到堆区                m_Age = new int(age);        }        //重载赋值运算符         Person& operator=(Person &p)        {                if (m_Age != NULL)                {                        delete m_Age;                        m_Age = NULL;                }                //编译器提供的代码是浅拷贝                //m_Age = p.m_Age;                //提供深拷贝 解决浅拷贝的问题                m_Age = new int(*p.m_Age);                //返回自身                return *this;        }        ~Person()        {                if (m_Age != NULL)                {                        delete m_Age;                        m_Age = NULL;                }        }        //年龄的指针        int *m_Age;};void test01(){        Person p1(18);        Person p2(20);        Person p3(30);        p3 = p2 = p1; //赋值操作        cout << "p1的年龄为:" << *p1.m_Age << endl;        cout << "p2的年龄为:" << *p2.m_Age << endl;        cout << "p3的年龄为:" << *p3.m_Age << endl;}int main() {        test01();        //int a = 10;        //int b = 20;        //int c = 30;        //c = b = a;        //cout << "a = " << a << endl;        //cout << "b = " << b << endl;        //cout << "c = " << c << endl;        system("pause");        return 0;}

5 关系运算符重载

**作用:**重载关系运算符,可以让两个自定义类型对象进行对比操作

示例:

class Person{public:        Person(string name, int age)        {                this->m_Name = name;                this->m_Age = age;        };        bool operator==(Person & p)        {                if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)                {                        return true;                }                else                {                        return false;                }        }        bool operator!=(Person & p)        {                if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)                {                        return false;                }                else                {                        return true;                }        }        string m_Name;        int m_Age;};void test01(){        //int a = 0;        //int b = 0;        Person a("孙悟空", 18);        Person b("孙悟空", 18);        if (a == b)        {                cout << "a和b相等" << endl;        }        else        {                cout << "a和b不相等" << endl;        }        if (a != b)        {                cout << "a和b不相等" << endl;        }        else        {                cout << "a和b相等" << endl;        }}int main() {        test01();        system("pause");        return 0;}

6 函数调用运算符重载

  • 函数调用运算符 () 也可以重载

  • 由于重载后使用的方式非常像函数的调用,因此称为仿函数

  • 仿函数没有固定写法,非常灵活

示例:

class MyPrint{public:        void operator()(string text)        {                cout << text << endl;        }};void test01(){        //重载的()操作符 也称为仿函数        MyPrint myFunc;        myFunc("hello world");}class MyAdd{public:        int operator()(int v1, int v2)        {                return v1 + v2;        }};void test02(){        MyAdd add;        int ret = add(10, 10);        cout << "ret = " << ret << endl;        //匿名对象调用          cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;}int main() {        test01();        test02();        system("pause");        return 0;}

感谢各位的阅读,以上就是"C++友元与运算符重载怎么应用"的内容了,经过本文的学习后,相信大家对C++友元与运算符重载怎么应用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

函数 运算 运算符 卧室 客厅 正在 成员 拷贝 数据 私有 内容 类型 全局 年龄 编译器 编译 C++ 应用 作用 属性 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京路客互联网科技有限公司 互联网下的科技发展 奇酷互联网科技 广州善班互联网科技 撒么互联网科技公司 济南华为互联网科技产业总部基地 中国的互联网科技企业的崛起 互联网经济与金融科技 智腾互联网科技有限公司 新兴科技互联网创新大赛颁奖典礼 广西互联网科技孵化中心 浙南科技城互联网大厦建设工程 群盈汇互联网科技有限公司 滨湖区互联网智能科技产品有哪些 互联网科技包装股 福建互联网展示科技馆设计 互联网领先科技活动 科技互联网专业工作会议发言稿 保山浩联互联网科技有限公司 东风日产互联网科技公司叫什么 百单网互联网科技有限公司怎么样 电子科技大学互联网 阿大互联网科技有限公司 民营互联网公司国防科技 互联网金融科技元年 上海钢联属于互联网科技股吗 从那以后互联网科技有限公司 工业互联网科技创业 新氧科技和美国互联网有关系吗 互联网科技和医药行业
0