析构器,友元友元类,重载 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

相关文章

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Mysql实现范围分区表(新增、删除、重组、查看)

《Mysql实现范围分区表(新增、删除、重组、查看)》MySQL分区表的四种类型(范围、哈希、列表、键值),主要介绍了范围分区的创建、查询、添加、删除及重组织操作,具有一定的参考价值,感兴趣的可以了解... 目录一、mysql分区表分类二、范围分区(Range Partitioning1、新建分区表:2、分