析构器,友元友元类,重载 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拷贝给b
intArray 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;
else
return 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 11
IntArray r=b2.operator+(b);//b.operator+(b2); //向b发送add消息,传递b2
r.show();
if(b<b2)
{
cout<<"b<b2"<<endl;
}
else
cout<<"b>=b2"<<endl;
//引用数组元素:
cout<<b[2]<<endl;
}
下一篇: 第一行代码Android 【学习笔记1】