类和对象(高级)

news2024/11/19 2:41:17

类和对象(高级)

一、运算符重载

运算符重载是对已有的运算符 指定新功能。不能创建新运算。
运算符重载关键字operator
思路:
1、弄懂运算符的运算对象的个数。(个数决定了 重载函数的参数个数)
2、识别运算符左边的运算对象 是类的对象还是其他.
类的对象:成员函数实现(推荐,少一个参数),全局函数实现(不推荐)
其他:只能是全局函数实现

1、重载<<运算符(全局函数实现)

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator <<(ostream &out,Person &ob );
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }
};
//返回cout的引用类型(可以链式输出)
ostream& operator <<(ostream &out,Person &ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
int main(int argc, char *argv[])
{
   Person lucy(100,"lucy",19.2f);
      Person bob(102,"bob",19.3f);
   cout<<lucy<<endl;
   //链式 输出
   cout<<lucy<<bob<<endl;
    return 0;
}

2、重载输入>>运算符

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person &ob );
    friend istream& operator>>(istream &in,Person &ob);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }

};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person &ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
int main(int argc, char *argv[])
{
   Person lucy;
   cin>>lucy;
   cout<<lucy<<endl;

    return 0;
}

如果使用全局函数 重载运算符 必须将全局函数设置成友元。

3、可以重载的运算符

在这里插入图片描述

4、重载加法运算符+(全局函数实现)

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person ob );
    friend istream& operator>>(istream &in,Person &ob);
    friend Person operator +(Person ob1,Person ob2);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }



};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}
//返回值不能为引用,因为temp是局部变量
Person operator +(Person ob1,Person ob2){
    Person temp;
    temp.num=ob1.num+ob2.num;
    temp.name=ob1.name+ob2.name;
    temp.score=ob1.score+ob2.score;
    return temp;

}
int main(int argc, char *argv[])
{
     Person lucy(100,"lucy", 88.8f);
     Person bob(101,"bob", 99.9f);
     Person tom(102,"tom", 77.7f);

     cout<<lucy+bob+tom<<endl;
     return 0;
}

5、重载加法运算符+(成员函数实现 推荐)

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person ob );
    friend istream& operator>>(istream &in,Person &ob);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }
//成员函数实现重载
  Person operator +(Person ob2){
      Person temp;
      temp.num=this->num+ob2.num;
      temp.name=this->name+ob2.name;
      temp.score=this->score+ob2.score;
      return temp;

  }


};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}

int main(int argc, char *argv[])
{
     Person lucy(100,"lucy", 88.8f);
     Person bob(101,"bob", 99.9f);
     Person tom(102,"tom", 77.7f);

     cout<<lucy+bob+tom<<endl;
     return 0;
}

6、重载==运算符(成员函数实现 推荐)

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person ob );
    friend istream& operator>>(istream &in,Person &ob);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }

  Person operator +(Person ob2){
      Person temp;
      temp.num=this->num+ob2.num;
      temp.name=this->name+ob2.name;
      temp.score=this->score+ob2.score;
      return temp;

  }
  //成员函数重载==运算符
  bool operator ==(Person &ob){
      if(num==ob.num&&name==ob.name&&score==ob.score){
          return true;
      }
      else{
          return false;
      }
  }


};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}

int main(int argc, char *argv[])
{
     Person lucy(100,"lucy", 88.8f);
//     Person bob(101,"bob", 99.9f);
          Person bob(100,"lucy", 88.8f);
if(lucy==bob){
cout<<"相等"<<endl;
}
else{

cout<<"不相等"<<endl;
}
     return 0;
}

7、重载++运算符

++a(前置++),它就调用operator++(a),
a++(后置++),它就会去调用operator++(a,int)

案例1:重载后置++

类名称 operator++(int)
{
 old=//先保存旧的值
//自增++
 return old;//返回旧值
 }
#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person ob );
    friend istream& operator>>(istream &in,Person &ob);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }

  Person operator +(Person ob2){
      Person temp;
      temp.num=this->num+ob2.num;
      temp.name=this->name+ob2.name;
      temp.score=this->score+ob2.score;
      return temp;

  }
  bool operator ==(Person &ob){
      if(num==ob.num&&name==ob.name&&score==ob.score){
          return true;
      }
      else{
          return false;
      }
  }

//后置++
  Person  operator ++(int a){
      Person old;
      old.num=num;
      old.name=name;
      old.score=score;

      num+=1;
      name+=name;
      score+=score;
      return old;
  }



};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}

int main(int argc, char *argv[])
{
    Person lucy(100,"lucy", 88.8f);
    Person bob;
     //先使用后++
     bob = lucy++;
     cout<<bob<<endl;
     cout<<lucy<<endl;
     return 0;
}

案例2:重载前置++

#include <iostream>
#include<string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &out,Person ob );
    friend istream& operator>>(istream &in,Person &ob);
private:
    int  num;
    string name;
    float score;
public:
    Person(){}
    Person(int num,string name,float score):num(num),name(name),score(score){

    }

  Person operator +(Person ob2){
      Person temp;
      temp.num=this->num+ob2.num;
      temp.name=this->name+ob2.name;
      temp.score=this->score+ob2.score;
      return temp;

  }
  bool operator ==(Person &ob){
      if(num==ob.num&&name==ob.name&&score==ob.score){
          return true;
      }
      else{
          return false;
      }
  }


  Person  operator ++(int a){
      Person old;
      old.num=num;
      old.name=name;
      old.score=score;

      num+=1;
      name+=name;
      score+=score;
      return old;
  }
//前置++
  Person operator ++(){
      num+=1;
      name+=name;
      score+=score;
      return *this;//返回自身的值
  }


};
//返回cout的引用类型(可以链式输出)
ostream& operator<<(ostream &out,Person ob ){
    out<<ob.num<<" "<<ob.name<<" "<<ob.score;
    return out;
}
istream &operator>>(istream &in,Person &ob){
in>>ob.num>>ob.name>>ob.score;
return in;
}

int main(int argc, char *argv[])
{
    Person lucy(100,"lucy", 88.8f);
     Person bob;
     //先++ 后使用
     bob = ++lucy;
     cout<<bob<<endl;
     cout<<lucy<<endl;
     // bob等于lucy
    
     return 0;
}

在这里插入图片描述

8、重载()运算符

重载()运算符 一般用于 为算法 提供策略。

#include <iostream>
using namespace std;
class Print{
public:
    void operator()(char *str){
        cout<<str<<endl;
    }

};



int main()
{
    Print ob;
    //对象和()结合 触发operator()成员函数 调用
    ob("Hello World");
    //匿名成员
    Print()("hello world");
    return 0;
}

二、自定义string类

重载构造函数

#include <iostream>
#include<string.h>
using namespace std;

class MyString{

private:
    int  size;
    char *str;
public:
    MyString();//无参构造
    MyString(char *str);//带参构造
    MyString(const MyString &ob);//深拷贝
    ~MyString();//析构函数
};

MyString::MyString(){

    str=NULL;
    size=0;
}
MyString::MyString(char *str){
    size=strlen(str);
    this->str=new char[size+1];
    memset(this->str,0,size+1);
    strcpy(this->str,str);
}


MyString::MyString(const MyString &ob){
    size=ob.size;
    str=new char[size+1];
    memset(str,0,size+1);
    strcpy(str,ob.str);
    
}

MyString::~MyString(){
    if(str!=NULL){
        delete[]str;
        str=NULL;
    }
}

int main(int argc, char *argv[])
{

    return 0;
}

重载输入输出(全局函数实现)

设为友元函数

friend ostream& operator<<(ostream &out,MyString ob);
friend istream& operator >>(istream &in,MyString &ob);

全局函数实现

ostream& operator<<(ostream &out,MyString ob){
    out<<ob.str;
    return out;
}
istream& operator >>(istream &in,MyString &ob){
    char  buff[1024]="";
    cin>>buff;
    if(ob.str!=NULL){
        delete[]ob.str;
        ob.str=NULL;
    }
    ob.size=strlen(buff);
    ob.str=new char[ob.size+1];
    memset(ob.str,0,ob.size+1);
    strcpy(ob.str,buff);
    return in;
}

重载括号运算符

在这里插入图片描述
类中声明,类外定义

 char& MyString::operator [](int pos){
     if(pos<0||pos>=size){
         cout<<"元素位置不合法"<<endl;
         exit(-1);
     }
     return str[pos];
 }

重载+运算符

在这里插入图片描述

类外实现

 MyString MyString::operator +(MyString ob){
     MyString temp;
     temp.size=size+ob.size;
     temp.str=new char[temp.size+1];
    memset( temp.str,0,temp.size+1);
    strcpy(temp.str,str);
    strcat(temp.str,ob.str);
    return temp;

 }

 MyString MyString::operator +(char *str)
 {
     MyString temp;
     temp.size=this->size+strlen(str);
     temp.str=new char[temp.size+1];
     memset(temp.str,0,temp.size+1);
     strcpy(temp.str,this->str);
     strcat(temp.str,str);
     return temp;
 }

重载=赋值运算符(深拷贝)

在这里插入图片描述

 MyString &MyString::operator =(MyString ob)
 {
     if(this->str!=NULL){
         delete[]this->str;
         this->str=NULL;
     }
     this->size=ob.size;
     this->str=new char[this->size+1];
     memset(this->str,0,this->size+1);
     strcpy(this->str,ob.str);
     return *this;
 }
 
 MyString &MyString::operator =(char *str)
 {
     if(this->str!=NULL){
         delete[]this->str;
         this->str=NULL;
     }
     this->size=strlen(str);
     this->str=new char[this->size+1];
     memset(this->str,0,this->size+1);
     strcpy(this->str,str);
     return *this;
 }

重载>运算符

在这里插入图片描述

 bool MyString::operator>(MyString ob)
 {
     if(str==NULL||ob.str==NULL){
         exit(-1);
     }
     if(strcmp(this->str,ob.str)>0){
         return  true;
     }
     else{
         return false;
     }
 }



 bool MyString::operator >(char *str)
 {
     if(str==NULL||this->str==NULL){
         exit(-1);
     }
     if(strcmp(this->str,str)>0){
         return  true;
     }
     else{
         return false;
     }
 }

三、智能指针

智能指针:解决 堆区空间的对象释放问题

前言:

#include <iostream>
using namespace std;
class Data{
public:
    Data(){
        cout<<"无参构造"<<endl;
    }
    ~Data(){
        cout<<"析构函数"<<endl;
    }
    void func(){
        cout<<"func函数"<<endl;
    }
};



int main()
{
    Data *ob=new Data();//通过new申请堆区空间


    return 0;
}

结果:只打印了无参构造,并没有调用析构函数

无参构造

设置智能指针

#include <iostream>
using namespace std;
class Data{
public:
    Data(){
        cout<<"无参构造"<<endl;
    }
    ~Data(){
        cout<<"析构函数"<<endl;
    }
    void func(){
        cout<<"func函数"<<endl;
    }
};

class SmartPointer{

private:
    Data *p;
public:
    SmartPointer(){}
    SmartPointer(Data *p){
        this->p=p;
    }
    ~SmartPointer(){
        delete p;
    }


};

int main()
{
    SmartPointer ob(new Data);


    return 0;
}

无参构造
析构函数

结果是调用了析构函数,运用的原理就是生命周期

我们在类中

    //重载*运算符
    Data& operator*(){
        return *p;
    }
    //重载->运算符
    Data* operator->(){
        return p;
    }
#include <iostream>
using namespace std;
class Data{
public:
    Data(){
        cout<<"无参构造"<<endl;
    }
    ~Data(){
        cout<<"析构函数"<<endl;
    }
    void func(){
        cout<<"func函数"<<endl;
    }
};

class SmartPointer{

private:
    Data *p;
public:
    SmartPointer(){}
    SmartPointer(Data *p){
        this->p=p;
    }
    ~SmartPointer(){
        delete p;
    }

    //重载*运算符
    Data& operator*(){
        return *p;
    }
    //重载->运算符
    Data* operator->(){
        return p;
    }

};

int main()
{
    SmartPointer ob(new Data);

//访问通过SmartPointer访问p
    ob.operator *().func();
    ob.operator->()->func();

    (*ob).func();
    ob->func();
    return 0;
}

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

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

相关文章

【css】伪元素实现跟随鼠标移动的渐变效果

主要功能是在按钮上实现鼠标跟随渐变效果。每当用户将鼠标移动到按钮上时&#xff0c;按钮会显示一个以鼠标位置为中心的渐变效果。 1. 核心部分: 监听鼠标在元素内移动 监听鼠标在元素内移动&#xff0c;并触发该事件。 const handleMouseMove (e: MouseEvent) > {if (…

C#知识|语法拾遗:数据类型转换

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 其实关于数据转换在任何语言中都会涉及&#xff0c;无论是PLC编程语言&#xff0c;还是SCADA开发中的脚本语言&#xff0c;都会涉及&#xff0c;在前边学习JavaScript的内容时&#xff0c;也看过相关内容&#xff1a; …

[RAG]喂饭教程!Neo4J可视化GraphRAG索引

GraphRAG通过结合知识图谱&#xff0c;增加RAG的全局检索能力。今天我将讲解如何使用Neo4J可视化GraphRAG索引的结果&#xff0c;以便进一步的处理、分析&#xff0c;以小说提取的实体《仙逆》为例&#xff0c;一图胜千言。本文分为4小节&#xff0c;安装neo4j、导入GraphRAG索…

如何做服务端渲染?

node server 接收客户端请求&#xff0c;得到当前的请求url 路径&#xff0c;然后在已有的路由表内查找到对应的组件&#xff0c;拿到需要请求的数据&#xff0c;将数据作为 props、context或者store 形式传入组件 然后基于 react 内置的服务端渲染方法 renderToString()把组件…

vue一键打不同环境的包

1.配置package.json 主要看的是 "build:all": "vue-cli-service build && vue-cli-service build --mode test && vue-cli-service build --mode development", "scripts": {"dev": "vue-cli-service serve"…

【SpringBoot源码】SpringBoot监听机制分析

目录 一、简介 二、SpringBoot事件监听机制 1)加载ApplicationListener监听器实现类 2)获取运行监听器EventPublishingRunListener 3)发布事件 4)Spring事件发布multicastEvent() 一、简介 接下来我们分析下SpringBoot的事件监听机制的源码。 二、SpringBoot事件监…

Android系统安全 — 1-OpenSSL支持的常用加解密算法介绍

常用加解密算法介绍 1. 哈希算法 常见的函数包含MD系列、SHA-1、SHA-2家族、SHA-3家族、SM3等。 1.1 MD5&#xff08;单向散列算法&#xff09; 全称是Message-Digest Algorithm 5&#xff08;信息-摘要算法&#xff09;&#xff0c;经MD2、MD3和MD4发展而来。MD5算法的使用…

线索精细化管理实践:线上推广渠道线索管理的8个要点

在如今线索获取成本越来越高的情况下&#xff0c;如何获取增量线索、经营好存量线索、实现精细化、高效率线索管理对于企业来说至关重要。获取线索是一切行动的开始&#xff0c;与其建立起稳定、持续的信任关系&#xff0c;达成合作甚至引导复购&#xff0c;是整个线索管理链路…

泛微eteams OA对接金蝶云星空写入数据

需求&#xff1a; 公司需要先在OA上对准备生产的订单进行一次量产评审&#xff0c;所有相关人员评审通过后才可以进行生产&#xff0c;导致下工单的人员每次需要把OA上的信息复制到ERP进行审批。 为什么不直接在ERP上审批呢&#xff1f; 首先该节点涉及到很多不用ERP的用户&am…

盘点八月份最好用的五款报表制作工具,涵盖各功能,你都听说过吗?

一、报表制作软件的重要性 在现代企业运营中&#xff0c;数据的处理和分析是至关重要的。如何将复杂的数据信息以直观、易懂的方式展现出来&#xff0c;是提升决策效率和准确性的关键。因此报表制作软件成为企业必备的工具之一&#xff0c;它们通过图表化的方式&#xff0c;帮…

加速网络体验,Squid缓存代理:让浏览如飞,畅享无限网络速度!

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言: squ…

低代码表单引擎的核心不仅仅是拖拉拽,深入解析表单的高级功能

作为一名专业的低代码产品经理&#xff0c;我们主要以 to B 的企业级系统为配置化对象&#xff0c;我深知在构建高效、用户友好的企业应用系统时&#xff0c;表单引擎扮演着核心基础的角色。当然拖拉拽快速创建页面是最简单直接的用户体验&#xff0c;然而&#xff0c;在享受拖…

Maven: 更新依赖索引清理maven仓库

文章目录 更新依赖索引清理maven仓库 更新依赖索引 有时候给 idea 配置完 maven 仓库信息后&#xff0c;在 idea 中依然搜索不到仓库中的 jar 包。这是因为仓库中的 jar 包索引尚未更新到 idea 中。这个时候我们就需要更新 idea 中 maven 的索引了&#xff0c;具体做法如下&am…

企业如何防止重要数据泄露?10个重要的小技巧!

在当今数字化时代&#xff0c;企业数据已成为其最宝贵的资产之一&#xff0c;但同时也面临着前所未有的泄露风险。数据泄露不仅可能导致财务损失&#xff0c;还可能损害企业声誉和客户信任。因此&#xff0c;采取有效措施防止重要数据泄露至关重要。以下是十个重要的小技巧&…

武威市旅游资源管理系统/旅游网站的设计与实现

摘要 经济快速发展带动下的旅游产业发展&#xff0c;在我国越来越被更多的人所追求。人们对获取旅游信息有很高的需求&#xff0c;在互联网发达的今天&#xff0c;制作一个旅游资源管理十分有必要。该设计根据基于jsp技术和MySQL数据库设计一个武威市旅游资源管理系统。系统的前…

自动化持续测试策略

目录 重新确定手动测试和自动化测试的关系 充分考虑自动化的可测性 尽量将自动化测试的粒度做细 策略实施的关键点 1.跨职能团队合作 2.持续学习 3.自动化测试的可测性 4.测试优化 在持续测试中&#xff0c;我们希望将每个测试分层上的测试都用自动化的方式来进行&…

C语言-内存管理

内存区间 在C语言中&#xff0c;内存被划分为以下几个区间&#xff1a; 栈&#xff08;stack&#xff09;&#xff1a;用于存储局部变量和函数的参数。栈是由编译器自动分配和释放的&#xff0c;栈的大小通常是固定的。 堆&#xff08;heap&#xff09;&#xff1a;用于存储动…

【Qt】输入类控件QComboBox

目录 输入类控件QComboBox 例子&#xff1a;使用下拉框模拟点餐 例子&#xff1a;从文件中加载下拉框的选项 输入类控件QComboBox QComboBox表示下拉框 核心属性 属性说明 currentText 当前选中的⽂本 currentIndex 当前选中的条⽬下标. 从 0 开始计算. 如果当前没有条…

秋招力扣Hot100刷题总结——栈和队列

1. 有效的括号 题目链接 题目要求&#xff1a;给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。…

Linux安装并配置Hadoop

目录 一、安装并配置JDK二、安装并配置Hadoop三、安装过程中遇到的问题总结 一、安装并配置JDK Linux上一般会安装Open JDK,关于OpenJDK和JDK的区别&#xff1a;http://www.cnblogs.com/sxdcgaq8080/p/7487369.html 准备Open JDK 1.8 查询可安装的java版本 yum -y list jav…