嵌入式养成计划-38----C++--匿名对象--友元--常成员函数和常对象--运算符重载

news2024/10/5 15:27:52

八十七、匿名对象

  • 概念:没有名字对象
  • 格式 :类名();
  • 作用
    1. 用匿名对象给有名对象初始化的
    2. 用匿名对象给对象数组初始化的
    3. 匿名对象作为函数实参使用

示例 :

#include <iostream>
using namespace std;
class Dog
{
private:
    string name;
    string color;
    int *age;
public:
    //无参构造函数
    Dog()
    {
        cout << "Dog::无参构造函数" << endl;
    }
    //有参构造函数
    Dog(string name, string c, int age):name(name),color(c),age(new int(age))
    {
        cout << "Dog::有参构造函数" << endl;
    }
    //拷贝构造函数
    Dog(const Dog &other):name(other.name),color(other.color),age(new int(*other.age))
    {
        cout << "Dog::拷贝构造函数" << endl;
    }
    //拷贝赋值函数
    Dog &operator=(const Dog &other)
    {
        if(this != &other)  //避免自己给自己赋值
        {
            name = other.name;
            color = other.color;
            age = new int(*other.age); //深拷贝赋值函数
        }
        cout << "Dog::拷贝赋值函数" << endl;
        return *this;
    }
    //析构函数
    ~Dog()
    {
        cout << "Dog::析构函数" << endl;
    }
};
void fun(Dog g)//Dog g = Dog("大黄","lll",6)
{
    //函数代码。。。
}
int main()
{
    Dog d1 = Dog("大黄","lll",6); //匿名对象给有名对象初始化
    Dog d[3] = {Dog("大","lll",6),Dog("黄","lll",6),Dog("大黄","lll",6)};
    
    fun(Dog("大黄","lll",6));  //匿名对象作为函数实参使用
    return 0;
}

八十八、友元

88.1 作用

  • 可以让其他一些函数或者类访问 另一个类的私有数据成员
  • 友元关键字 : friend

88.2 种类

  1. 全局函数做友元
  2. 类友元
  3. 成员函数做友元

88.3 全局函数做友元

  • 让全局函数访问一个类私有数据成员。

示例 :

#include <iostream>
using namespace std;
class Room {
    friend void room_friend(Room &r);
private:
    string keting;
public:
    string zoulang;

    Room();
};
Room::Room(){
    this->keting = "客厅";
    this->zoulang = "走廊";
}
void room_friend(Room &r){
    cout << "全局友元函数在访问->" << r.zoulang <<endl;
    cout << "全局友元函数在访问->" << r.keting <<endl;
}
int main()
{
    Room r1;
    room_friend(r1);
    return 0;
}

88.4 类做友元

  • 一个类去访问另一个类的私有属性。

88.5 成员函数做友元

  • 一个类里的成员函数去访问另一个类的私有属性。

88.6 示例

#include <iostream>
using namespace std;

class Room;

class Friend_Room{
private:
    Room *r;
public:
    Friend_Room();
    void access_room();
};

class Room {
//    friend class Friend_Room;
    friend void Friend_Room::access_room();
private:
    string keting;
public:
    string zoulang;
    
    Room();
};
Room::Room(){
    this->keting = "客厅";
    this->zoulang = "走廊";
}

Friend_Room::Friend_Room(){
    this->r = new Room;
    cout << "Friend_Room 的 构造函数" << endl;
}
void Friend_Room::access_room(){
    cout << "Friend_Room 正在访问 " << this->r->zoulang << endl;
    cout << "Friend_Room 正在访问 " << this->r->keting << endl;
}

int main()
{
    Friend_Room f_r;
    f_r.access_room();
    return 0;
}

88.7 注意

  • 不要过度使用友元,会降低或者破坏封装性
  • 友元不具有交互性,传递性,继承性。

八十九、const修饰的成员函数和对象(常成员函数、常对象)

  • 类中所有的成员函数都可以对类中数据成员进行修改操作,
  • 如果想设计一个成员函数不能对数据成员修改操作,则需要用const修饰的成员函数实现。

89.1 常成员函数

  • 常成员函数 :表示该成员函数不能修改数据成员的值。
  • 格式 :
    返回值类型 函数名(形参列表) const 
    {
        函数体内容;
    }
    
  • 同名的常成员函数和非常成员函数构成重载关系,
    • 原因:this指针类型不同

89.2 常对象

  • 常对象表示这个对象的数据成员不能被修改。
  • 格式: const 类名 对象名;
  1. 非常对象可以调用常成员函数,也可以调用非常成员函数,优先调用非常成员函数
  2. 常对象只能调用常成员函数,如果没有常成员函数,则报错

示例 :

#include <iostream>
using namespace std;

class Stu
{
private:
    string name;
    int id;
public:
    Stu(){}
    Stu(string  name, int id):name(name),id(id)
    {}
    //常成员函数
    void display() const //this指针原型: Stu const * const this;
    {
        //this->name = "lisi"; 常成员函数不能对数据成员修改
        cout << name <<"  "  << id << endl;
    }
    //非常成员函数
    void display() //this指针原型: Stu * const this;
    {
        this->name = "lisi";
        cout << name <<"  "  << id << endl;
    }
};
int main()
{
    const Stu s1("zhangsan", 1001);   //常对象
    s1.display(); //常对象只能调用常成员函数


    return 0;
}

89.3 mutable关键字

  • mutable修饰成员变量,表示该成员变量可以在常成员函数中被修改 (取消常属性)
    在这里插入图片描述

九十、运算符重载

  • 概念:
    运算符重载就是对运算符重新定义,赋予另一种功能,以适应不同的数据类型。
  • 每种运算符重载都有两种实现方式:
    1. 成员函数实现运算符重载
    2. 全局函数实现运算符重载

90.1 算术运算符重载

种类: +  -   *  /    %
表达式: L   ?   R    (L 左操作数     ?运算符    R右操作数)
左操作数:可以是左值,可以右值,运算过程中不可以被改变
右操作数:可以是左值,可以右值,运算过程中不可以被改变
结果:右值 (不可以被改变)
  • 算术运算符重载实现方式:
    1. 成员函数实现运算符重载

      const 类名 operator#(const 类名 &R) const 
      {
      	具体实现
      }
      

      第一个const 表示结果是右值 不能被改变
      第二个const 表示右操作数运算过程中不能被改变
      第三个const 表示左操作数运算过程中不能被改变

    2. 全局函数实现运算符重载

      const 类名 operator#(const 类名 &L, const 类名 &R)
      {
      	具体实现
      }
      

示例 :

#include <iostream>
using namespace std;

class Person
{
    friend const Person operator+(const Person &L, const Person &R);
private:
    int a;
    int b;
public:
    Person(){}
    Person(int a, int b):a(a),b(b){}
    
    //成员函数实现+号运算符重载
//    const Person operator+(const Person &p) const
//    {
//        Person temp;
//        temp.a = a + p.a;
//        temp.b = b + p.b;
//        return temp;
//    }
    void show()
    {
        cout << " a = " << a << "    b = " << b << endl;
    }
};

//全局函数实现+运算符重载
const Person operator+(const Person &L, const Person &R)
{
    Person temp;
    temp.a = L.a + R.a;
    temp.b = L.b + R.b;
    return temp;
}
int main()
{
    Person p1(10,10);
    Person p2(10,10);
    //成员函数
    //简化版本
    //Person p3 = p1 + p2; //本质上 Person p3 = p1.operator+(p2)
    Person p3 = p1 + p2; //本质上 Person p3 = operator+(p1, p2)
    p3.show();
    return 0;
}

90.2 关系运算符重载

种类: > 、 >= 、 <、 <=、  ==、  !=
表达式: L   ?   R    (L 左操作数     ?运算符    R右操作数)
左操作数:可以是左值,可以右值,运算过程中不可以被改变
右操作数:可以是左值,可以右值,运算过程中不可以被改变
结果: bool类型
  • 关系运算符重载实现方式:
    1. 成员函数实现运算符重载
      bool operator#(const 类名 &R) const
      {
      	具体实现
      }
      
    2. 全局函数实现运算符重载
      bool operator#(const 类名 &L, const 类名 &R)
      {
      	具体实现
      }
      

示例 :

#include <iostream>
using namespace std;
//
class Person
{
    friend bool operator>(const Person &L, const Person &R);
private:
    int a;
    int b;
public:
    Person(){}
    Person(int a, int b):a(a),b(b){}
    //成员函数实现>号运算符重载
//    bool operator>(const Person &R) const
//    {
//        if(a>R.a && b>R.b)
//        {
//            return true;
//        }
//        else
//        {
//            return false;
//        }
//    }
    void show()
    {
        cout << " a = " << a << "    b = " << b << endl;
    }
};
//全局函数实现>号运算符重
bool operator>(const Person &L, const Person &R)
{
    if(L.a>R.a && L.b>R.b)
    {
        return true;
    }
    else
    {
        return false;
    }
}
int main()
{
    Person p1(10,10);
    Person p2(10,10);
    if(p3 > p2)  //本质上  p3.operator>(p2)
    //本质上 operator(p3,p2)
    {
        cout <<"p3>p2" << endl;
    }
    return 0;
}

90.3 赋值运算符重载

种类: = 、+= 、 -= 、*= 、/=  、%=
表达式: L   ?   R    (L 左操作数     ?运算符    R右操作数)
左操作数:是左值,运算过程中要被改变
右操作数:可以是左值,可以右值,运算过程中不可以被改变
结果:自身的引用
  • 赋值运算符重载实现方式:
    1. 成员函数实现运算符重载
      类名 &operator#(const 类名 &R) 
      {
      	具体实现
      }
      
    2. 全局函数实现运算符重载
      类名 &operator#(类名 &L, const 类名 &R) 
      {
      	具体实现
      }
      

示例 :

#include <iostream>
using namespace std;

class Person
{
    friend Person &operator+=(Person &L,const Person &R);
private:
    int a;
    int b;
public:
    Person(){}
    Person(int a, int b):a(a),b(b){}
    //成员函数实现+=号运算符重载
//    Person &operator+=(const Person &R)
//    {
//        a += R.a; // a = a + R.a
//        b += R.b;
//        return *this;
//    }
    void show()
    {
        cout << " a = " << a << "    b = " << b << endl;
    }
};
//全局函数实现+=号运算符重载
Person &operator+=(Person &L,const Person &R)
{
    L.a += R.a; // a = a + R.a
    L.b += R.b;
    return L;
}
int main()
{
    Person p1(10,10);
    Person p2(10,10);
    p3+=p2;  //  p3 = p3 + p2    本质上 p3.operator+=(p2)
    p3.show();
    return 0;
}

小作业

  • 整理代码
    • 算术运算符
    • 逻辑运算符
    • 赋值运算符

我写的

#include <iostream>

using namespace std;

class Stu {
    //逻辑运算符重载的全局友元函数
    friend bool operator>(const Stu &l, const Stu &r);
    friend bool operator>=(const Stu &l, const Stu &r);
    friend bool operator<(const Stu &l, const Stu &r);
    friend bool operator<=(const Stu &l, const Stu &r);
    friend bool operator==(const Stu &l, const Stu &r);
    friend bool operator!=(const Stu &l, const Stu &r);

    //赋值运算符重载
    friend Stu &operator+=(Stu &l, const Stu &r);
    friend Stu &operator-=(Stu &l, const Stu &r);
    friend Stu &operator*=(Stu &l, const Stu &r);
    friend Stu &operator/=(Stu &l, const Stu &r);
    friend Stu &operator%=(Stu &l, const Stu &r);
private:
    double high;
    double weight;
public:
    Stu(){}
    Stu(double h, double w):high(h),weight(w){}
    void show(){
        cout << "high = " << this->high << endl;
        cout << "weight = " << this->weight << endl;
        puts("");
    }

    //类内实现运算符重载
    //算术运算符重载
    const Stu operator+(const Stu &s)const{
        Stu t;
        t.high = this->high + s.high;
        t.weight = this->weight + s.weight;
        return t;
    }
    const Stu operator-(const Stu &s)const{
        Stu t;
        t.high = this->high + s.high;
        t.weight = this->weight + s.weight;
        return t;
    }

    const Stu operator*(const Stu &s)const{
        Stu t;
        t.high = this->high + s.high;
        t.weight = this->weight + s.weight;
        return t;
    }

    const Stu operator/(const Stu &s)const{
        Stu t;
        t.high = this->high + s.high;
        t.weight = this->weight + s.weight;
        return t;
    }

    const Stu operator%(const Stu &s)const{
        Stu t;
        t.high = (int)this->high % (int)s.high;
        t.weight = (int)this->weight % (int)s.weight;
        return t;
    }

    //重载赋值运算符
    const Stu &operator=(const Stu &s){
        this->high = s.high;
        this->weight = s.weight;
        return *this;
    }
};

/*
 * 全局函数实现运算符重载
 * 访问类的私有属性需要添加为类的友元函数
*/
//逻辑运算符重载
bool operator>(const Stu &l, const Stu &r){
    if(l.high > r.high && l.weight > r.weight)
        return true;
    return false;
}
bool operator>=(const Stu &l, const Stu &r){
    if(l.high >= r.high && l.weight >= r.weight)
        return true;
    return false;
}
bool operator<(const Stu &l, const Stu &r){
    if(l.high < r.high && l.weight < r.weight)
        return true;
    return false;
}
bool operator<=(const Stu &l, const Stu &r){
    if(l.high <= r.high && l.weight <= r.weight)
        return true;
    return false;
}
bool operator==(const Stu &l, const Stu &r){
    if(l.high == r.high && l.weight == r.weight)
        return true;
    return false;
}
bool operator!=(const Stu &l, const Stu &r){
    if(l.high != r.high && l.weight != r.weight)
        return true;
    return false;
}


//赋值运算符重载
Stu &operator+=(Stu &l, const Stu &r){
    l.high += r.high;
    l.weight += r.weight;
    return l;
}
Stu &operator-=(Stu &l, const Stu &r){
    l.high -= r.high;
    l.weight -= r.weight;
    return l;
}
Stu &operator*=(Stu &l, const Stu &r){
    l.high *= r.high;
    l.weight *= r.weight;
    return l;
}
Stu &operator/=(Stu &l, const Stu &r){
    l.high /= r.high;
    l.weight /= r.weight;
    return l;
}
Stu &operator%=(Stu &l, const Stu &r){
    l.high  = (int)l.high % (int)r.high;
    l.weight = (int)l.weight % (int)r.weight;
    return l;
}

int main()
{
    Stu s1(175, 60);
    Stu s2(170, 55);

    Stu s3 = s1 + s2;
    Stu s4 = s1 - s2;
    Stu s5 = s1 * s2;
    Stu s6 = s1 / s2;
    Stu s7 = s1 % s2;

    s1.show();
    s2.show();
    s3.show();
    s4.show();
    s5.show();
    s6.show();
    s7.show();

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1077327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小程序如何设置各种时间参数

在小程序管理员后台->基本设置处&#xff0c;可以设置各种时间。例如待支付提醒时间、待支付取消时间、自动发货时间、自动收货时间、自动评价时间等等。下面具体解释一下各个时间的意思。 1. 待支付提醒时间&#xff1a;在用户下单后&#xff0c;如果一段时间内没有完成支付…

IDEA的使用(一)代码模块的导入、快捷使用、自定义 (IntelliJ IDEA 2022.1.3版本)

目录 1. IDEA项目结构 2. 模块的导入操作 2.1 正规操作 2.2 取巧操作 2.3 出现乱码 2.4 模块改名 3. 代码模板的使用 后缀补全&#xff08;Postfix Completion&#xff09;、实时模板&#xff08;Live Templates&#xff09;菜单里面什么介绍都有&#xff0c;可以自学&a…

C#(Csharp)我的基础教程(四)(我的菜鸟教程笔记)-Windows项目结构分析、UI设计和综合事件应用的探究与学习

目录 windows项目是我们.NET学习一开始必备的内容。 1、窗体类&#xff08;主代码文件窗体设计器后台代码文件&#xff09; 主窗体对象的创建&#xff1a;在Program类里面&#xff1a; Application.Run(new FrmMain());这句代码就决定了&#xff0c;当前窗体是项目的主窗体。…

Python Opencv实践 - 车辆识别(1)读取视频,移除背景,做预处理

示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。代码仅供参考。 import cv2 as cv import numpy as np#读取视频文件 video cv.VideoCapture("../../SampleVideos/Traffic.mp4") FPS 10 DELAY int(1000 / FPS) kernel cv.getStructu…

Python数据容器——字典的常用操作(增、删、改、查)

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注. 目录 一、理解字典 1. Python字典是什么&#xff1f; 2. 字…

隆重宣布:.NET 8 RC1 现已推出

作者&#xff1a;Leslie Richardson 排版&#xff1a;Alan Wang .NET 8 RC1 现已推出。这是我们两个候选版本中的第一个。此版本包括适用于 Android 和 WASM 的新 AOT 模式、System.Text.Json 改进以及对容器的 Azure Managed Identity 支持。如果您还没有开始学习和测试 .NET …

基于Java+SpringBoot+Vue民宿管理系统的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

android Google官网 :支持不同的语言和文化 rtl / ltr : 本地化适配:RTL(right-to-left) 适配

参考 google官网&#xff1a; 支持不同的语言和文化 应用包含可能专门针对特定文化而设计的资源。例如&#xff0c;应用可以包含针对特定文化的字符串&#xff0c;这些字符串将转换为当前语言区域的语言。 将具有文化特异性的资源与应用的其他资源分开是一种很好的做法。And…

Apache Doris 数据建模之 Aggregate Key 模型

了解 Doris 数据模型对于我们使用 Doris 来解决我们业务问题非常重要&#xff0c;这个系列我们将详细介绍 Doris 的三种数据模型及 Doris 数据分区分桶的一些策略&#xff0c;帮助用户更好的使用 Doris 。 这个系列我会讲解 Doris 的三种数据模型及在这三种数据模型之上的 Rol…

算法练习11——买卖股票的最佳时机 II

122. 买卖股票的最佳时机 II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获得…

【移植代码】matlab.engine报错、numpy+mkl安装、Qt platform plugin报错总结

文章目录 numpy报错numpy安装PyQt5报错matlab.engine无法加载确认配置版本进行配置 matlab文件路径缺失vscode无法debug3.7以下版本总结 今天的任务是复现师姐的代码&#xff0c;代码在服务器的环境下可以跑&#xff0c;而我要做的&#xff0c;就是将环境和源码配置好&#xff…

Python库学习(九):Numpy[续篇三]:数组运算

NumPy是用于数值计算的强大工具&#xff0c;提供了许多数组运算和数学函数&#xff0c;允许你执行各种操作&#xff0c;包括基本运算、统计计算、线性代数、元素级操作等 1.基本运算 1.1 四则运算 NumPy数组支持基本的四则运算&#xff08;加法、减法、乘法和除法&#xff09;…

mysql面试题31:一条SQL语句在MySQL中如何执行的

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:一条SQL语句在MySQL中如何执行的 以下是一条SQL语句在MySQL中的详细执行步骤: 语法分析:MySQL首先对SQL语句进行语法分析,检查SQL语句是否符合…

算法题:分发饼干(典型的贪心算法问题)

这个题目是一个典型的贪心算法问题&#xff0c;解决思路是排序双指针贪心法&#xff0c;先将两个数组分别排序&#xff0c;优先满足最小胃口的孩子。&#xff08;本题完整题目附在了最后面&#xff09; 代码如下&#xff1a; class Solution(object):def findContentChildren(…

如何使用 ONLYOFFICE API 转换办公文档格式

作者&#xff1a;天哥 上一期我们介绍了 ONLYOFFICE 的文档生成器API接口函数库。这一期我们继续介绍ONLYOFFICE 的文件转换API接口函数库。 为什么要使用 ONLYOFFICE 转换API ONLYOFFICE 转换 API 有助于转换大部分类型的Office文档&#xff1a;文本、表格、幻灯片、表单、P…

Visual Studio 2022新建项目时没有ASP.NET项目

一、Visual Studio 2022新建项目时没有ASP.NET项目 1、打开VS开发工具&#xff0c;选择工具菜单&#xff0c;点击“获取工具和功能” 2、选择“ASP.NET和Web开发”和把其他项目模板&#xff08;早期版本&#xff09;勾选上安装即可

C/C++实现简单高并发http服务器

基础知识 html&#xff0c;全称为html markup language&#xff0c;超文本标记语言。 http&#xff0c;全称hyper text transfer protocol&#xff0c;超文本传输协议。用于从万维网&#xff08;WWW&#xff1a;World Wide Web&#xff09;服务器传输超文本到本地浏览器的传送…

网络安全(黑客)—小白自学

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

什么牌子洗地机最好最实用?口碑最好的洗地机排名

洗地机具备吸拖扫洗一体的特点&#xff0c;专治各种懒病&#xff0c;面对众多的洗地机&#xff0c;对于一些新手来说一时之间无从选择&#xff0c;今天笔者给大家介绍几款近期口碑比较好的家用洗地机。 洗地机洗地机合适的人群&#xff1a; 家里有小宝宝&#xff1a;一般2-10…

前端js八股文大全

一、js的数据类型 值类型(基本类型)&#xff1a;数字(Number)、字符串&#xff08;String&#xff09;、布尔(Boolean)、对空&#xff08;Null&#xff09;、未定义&#xff08;Undefined&#xff09;、Symbol,大数值类型(BigInt) 引用数据类型&#xff1a;对象(Object)、数组…