析构器,友元友元类,重载 operator 运算符,动态数组的实现

本文主要是介绍析构器,友元友元类,重载 operator 运算符,动态数组的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1类:一类事物的抽象(模板)
  定义:  class 类名
          {
            //方法
            //属性
          };
2、实例化对象:构造器分配空间并初始化
3、析构器:一个类对象需要作善后处理。
   什么时候来执行:当类对象被释放时,系统会通知对象(发送释放消息)。
   ~类名()    ;//不带形参
   注:1、只有一种析构器(不能重载 )
       2、默认添加析构函数(空函数体)
       3、堆区必须由delete来释放,否则不会被析构

4、友元
      1、友元函数:就是全局函数作为类的朋友
        作用:友元函数可以访问该类的非公有成员
        class 类名
       {
            //声明 
            friend 返回类型   函数名(...)
       };
    
            返回类型   函数名(...)
           {
           }

      2、友元类:若类A需要去访问类B的非公成员,则A声明为B的友元类,那么A就
           访问类B的非公有成员
          class B
          {
           ...
          friend class A;
           private:
           ...
          };
          class A
         {
          //访问B的成员
          ...    
         B b;
         }
         注:友元会破坏封装性。    

5、重载运算符:    将运算重载为可以对复杂类型进行运算。
    运算符:就是提供运算操作,
    运算表达式:运算的结果
    1、运算符的数据可以对基本类型进行运算。
    定义:   返回类型  operator运算符(形参);

1、算术运算符:
        1、全局函数
            返回值 operator运算符(形参1,形参2)
        2、成员方法
            friend 返回值 operator运算符(形参1)
    2、判断运算符: >  < !=  >=  <=  ==
        结果: 真  假
        1、成员方法:
        2、全局函数:
    3、下标运算符 []
        1、成员方法:
    4、    重载输入输出流:
        输出:<<
        输入:>>
        两个标准输出输出流:cout/cin分别是类ostream/istream的对象
        重载:
        1全局函数
            void operator<<(ostream&,对象);
        2、不能为成员方法
        
        
    注:1、下列运算符不能重载:
        sizeof  对象->成员   new   *  &   对象.成员
        2、规定:对复杂类型重载运算符的结果类型必须保持与运算的表达式结果一致。
        3、语法规则:运算符的操作数目不能改变
        
    4、自增/自减:
        1、全局函数
            类 operator++(类);  前自增
            类 operator++(类,int)
        2成员方法
            类 operator++()    //前自增
            类 operator++(int)


4、数据区间:
  1、动态区:当函数被调用时,动态变量(在函数内定义的非staic变量)会被分配空间
        注:栈区变量(所有动态空间存储在栈区)
  2、静态区:在程序运行时主分配空间(全局,static)
  3、堆区:由malloc/new来分配的空间,只能由free/delete来释放

   析构器 , 析构函数的使用:

#include<iostream>
using namespace std;//定义类
class people
{
//方法
public:
//构造器:people();people(int);	
//析构器:~people();
//属性
protected:int id;
};
//类外定义
//构造
people::people():id(0)
{cout<<"被people()构造啦"<<endl;
}
people::people(int i):id(i)
{cout<<i<<"被people(int)构造啦"<<endl;
}//析构
people::~people()
{cout<<this->id<<"对象被释放啦"<<endl;
}
/*
//静态区
people p1(2);
people p2(3);
people p3(4);
*/
int main()
{
//实例化对象:动态区
/*people p;//无参构造器people p1(3);people p2(4);
*/
//堆区:只能new来申请空间,然后必须有delete来释放people* p=new people(1);//返回一个堆区地址	delete p;
}
#include<iostream>
using namespace std;class people
{
public://构造器:people(int);void show();~people();
protected:int* data;//指针变量:存放地址
};
people::people(int d)
{cout<<"people对象被构造啦"<<endl;//先申请空间this->data=new int;//赋值*data=d;
}
//显示
void people::show()
{cout<< *data <<endl;
}
//析构器:
people::~people()
{cout<<"对象死亡"<<endl;delete this->data;	
}void fun()
{cout<<"fun被调用"<<endl;
//实例化对象:people p(1);cout<<"fun运行结束"<<endl;
}
int main()
{//调用fun函数fun();	
}

   动态数组的实现 : 

#include<iostream>
using namespace std;
//定义结构体:结点
struct Node
{int data;//数据struct Node* next;//指向域
};//整型数组:动态数组
class intArray
{
//方法
public:intArray();	//插入元素void add(int);//插入指定位置void add(int pos,int d);void list();~intArray();//析构函数
//属性
private:Node* pArray;//存储头节点地址Node* pLast;
};
//类外定义
intArray::intArray()
{this->pArray=NULL;this->pLast=NULL;
}
//增加元素
void intArray::add(int d)
{
//链表:
//1分配空间Node* pnew=new Node;	//分配空间pnew->data=d;//赋值数据pnew->next=NULL;
//2修改指向域:if(NULL==this->pArray)	{this->pArray=pnew;}else{this->pLast->next=pnew;}this->pLast=pnew;
}
//重载插入:将d插入到第pos的位置后面
void intArray::add(int pos,int d)
{Node* ploc=this->pArray;//ploc从头开始while(ploc!=NULL&&pos){pos--;ploc=ploc->next;}//1分配空间Node* pnew=new Node;pnew->data=d;pnew->next=NULL;			//头节点if(NULL==pArray)//链表不存在{this->pArray=pnew;this->pLast=pnew;}else if(0==pos){pnew->next=this->pArray;//成为头节点this->pArray=pnew;			}else if(NULL==ploc)//尾{this->pLast->next=pnew;this->pLast=pnew;}else//中间节点{pnew->next=ploc->next;ploc->next=pnew;	}
}
void intArray::list()
{Node* ploc=this->pArray;while(ploc!=NULL){cout<<ploc->data<<" ";ploc=ploc->next;//指向下一个元素}cout<<endl;}
intArray::~intArray()
{Node* ploc=this->pArray;while(ploc!=NULL){pArray=ploc->next;//先将头节点指针指向一个delete ploc;ploc=pArray;}//析构函数cout<<"对象被析构啦"<<endl;
}
int main()
{
//定义数组:int buf[10];
//对象:构造器intArray a;	a.add(1);a.add(2);a.add(3);a.add(4);
//遍历a.list();//将a拷贝给bintArray b(a);b.list();return 0;
}

   在 析构的时候 遍历了一下,

    intArray::~intArray()
    {
           Node* ploc=this->pArray;
           while(ploc!=NULL)
           {
                  pArray=ploc->next;
                  //先将头节点指针指向一个
                  delete ploc;
                  ploc=pArray;
            }
                 //析构函数
                 cout<<"对象被析构啦"<<endl;
     }

   下图 : 是还没有将头节点指向  ploc->next 的.

   下图 : 实现了 pArray=ploc->next; 等待释放中间节点 .

   下图 : 释放掉了   delete ploc;    并且将  ploc=pArray;

    友元 : 

#include<iostream>
using namespace std;
//定义类:封装
class people
{
//方法
public:people(int a,int b){ia=a;ib=b;	}//声明:将show(people&)声明为此类的朋友函数friend void show(people& );
//属性
private:int ia;int ib;
};
//全局函数
void show(people& xy)
{xy.ia=0; // ia是私有的,类外不可以访问	,但由于show是people朋友,故可以访问//cout<<ym.ia<<endl;//不能引用cout<<xy.ia<<endl;}
int main()
{
//实例化对象people ym(1001,2002);show(ym);//cout<<ym.ia<<endl;  main不是people的朋友,不能访问该类的非公有成员
}

   友元类,实现类与类的共享 .

#include<iostream>
using namespace std;
//类外不能访问非公有成员
class score
{
public:friend class stu;
private:int a;int b;
};class stu
{
public:void show(){cout<<s.a<<endl;  //s.a是私有的,score类外不能访问,但由于stu是score的朋友,所以stu中也可以访问score的非公有的成员}
private:int id;//整型score s;//对象
};
int main()
{score s;//cout<<s.a<<endl;//error
}

   重载运算符 , operator .

#include<iostream>
using namespace std;
//xy
class point
{
public://无参构造point(){}//有参构造point(int i,int j){x=i;y=j;}void show(){cout<<"x:"<<x<<" y:"<<y<<endl;}	//友元friend point add(point&,point&);friend point operator+(point&,point&);
private:int x;int y;
};
//返回值
point    add(point& px,point& py)
{//实例化对象point result;//构造函数   point()result.x=px.x+py.x;result.y=px.y+py.y;return result;
}
//全局:不能访问非公有的
point  operator+(point& pa,point& pb)
{cout<<"operator+(...)"<<endl;point result;result.x=pa.x+pb.x;result.y=pa.y+pb.y;return result;
}
int main()
{
//运算符:
//算术运算cout<< 1+2 <<endl;  //+基本类型
//实例化:point p1(1,2);p1.show();point p2(2,3);//p1+p2;	   运算符只能基本类型//调用add函数point r;r=add(p1,p2);r.show();//调用 函数名(形参)point r2=p1+p2;//operator+(p1,p2);r2.show();//????point r3=p1-p2;
}

   重载运算符 , operator 2 (重载的是整型的值,不是字符串)

#include<iostream>
#include<string.h>
#include<stdarg.h>
using namespace std;class IntArray
{
public:friend bool operator<(IntArray&,IntArray&);IntArray(int num,...)//第一个形参:显示类型 {//个数this->ilen=num;va_list l;	//1初始化va_start(l,num);int i=0;//2取实参for(i=0;i<num;i++){buf[i]=va_arg(l,int);}//3释放va_end(l);}	void show(){int i=0;for(i=0;i<ilen;i++){cout<<buf[i]<<" ";}cout<<endl;}//operator函数相加:返回新的数组IntArray operator+(IntArray& i){IntArray result(0);result.ilen=this->ilen+i.ilen;memcpy(result.buf,this->buf,sizeof(int)*(this->ilen));//内存拷贝 	/*for(int i=0;i<this->ilen;i++)result.buf[i]=this->buf[i];*/memcpy(result.buf+this->ilen,i.buf,sizeof(int)*(i.ilen));return result;}//重载  >判断运算符  判断假  真bool operator>(IntArray& a){//1逐个元素比较//2.和比较int num1=0,num2=0;int i=0;for(i=0;i<this->ilen;i++){num1+=this->buf[i];}for(i=0;i<a.ilen;i++){num2+=a.buf[i];}if(num1>num2)return true;elsereturn false;}//下标法int operator[](int index){return this->buf[index];}
private:int buf[100];//容量int ilen;//存储元素的个数
};
//全局函数:  bool operator<(...,...)
bool operator<(IntArray& b1,IntArray& b2)
{//内部去判断return true;
}int main()
{//实例化对象:IntArray b(4,1,2,3,4);	//可变形参b.show();IntArray b2(5,7,8,9,10,11);b2.show();//重载//b+b2;//1 2 3 4 5 6 7 8 9 10 11IntArray r=b2.operator+(b);//b.operator+(b2);	//向b发送add消息,传递b2r.show();if(b<b2){cout<<"b<b2"<<endl;}elsecout<<"b>=b2"<<endl;
//引用数组元素:cout<<b[2]<<endl;
}

这篇关于析构器,友元友元类,重载 operator 运算符,动态数组的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/744808

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima