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

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while