一、对象指针
对象占用一块连续的内存区域,可以使用一个指向对象的指针来访问对象,即对象指针,它指向存放该对象的地址。
可以用类来定义对象指针变量,通过对象指针来访问对象的成员,定义形式如下:
类名 * 对象指针名;
对象指针采用 ->运算符访问公有数据成员和成员函数
对象指针名 ->数据成员名
对象指针名 ->成员函数名(参数表)
使用对象指针作为函数的参数有以下好处:
- 实现地址传递:通过在调用函数时将实参对象的地址传递给形参指针对象,使二者指向同一内存地址,这样对象指针所指向对象的改变也将同样影响实参对象,从而实现信息的双向传递;
- 使用对象指针效率高:传递的只是对应实参对象的地址,不需要实现对象之间的副本复制,减小时空开销,提高运行效率。
二、对象引用
就是对某类对象定义一个引用,实质是通过将被引用对象的地址赋给引用对象,使二者指向同一个内存空间,这样引用对象就成为被引用对象的别名。
定义一个对象引用并同时指向一个对象的方式:
类名 & 对象引用名 = 被引用对象;
- 对象引用和被引用对象必须是同类型的;
- 除非是作为函数参数或者函数返回值,对象引用在定义时必须要初始化;
- 定义一个对象引用并没有定义一个对象,所以不分配任何内存,不调用构造函数;
- 对象引用通常用作函数的参数,不仅具有对象指针的优点,而且比对象指针更简洁、方便、直观。
对象引用的使用格式:
对象引用名.数据成员名
或
对象引用名.成员函数名(参数表)
Clock c1(8,20,20);
Clock & cr=c1;
cr.ShowTime();
例子:时间加法。
实现一个时钟类:
#include
using namespace std;
class Clock
{
private:
int H,M,S;
public:
void setTime(int h,int m,int s)
{
H=h,M=m,S=s;
}
void ShowTime()
{
cout<<H<<":"<<M<<":"<<S<<endl;
}
//构造函数,带有默认形参值
Clock(int h=0,int m=0,int s=0)
{
H=h,M=m,S=s;
}
//拷贝构造函数
Clock(Clock & p)
{
H=p.H,M=p.M,S=p.S;
}
//函数重载
void TimeAdd(Clock * Cp);
void TimeAdd(int h,int m,int s);
void TimeAdd(int s);
};
//对象指针,实现两个时间相加
void Clock:: TimeAdd(Clock * Cp)
{
H=(Cp->H+H+(Cp->M+M+(Cp->S+S)/60)/60)%24;
M=(Cp->M+M+(Cp->S+S)/60)%60;
S=(Cp->S+S)%60;
}
//对象引用
void Clock::TimeAdd(Clock & Cr)
{
H=(Cr.H+H+(Cr.M+M+(Cr.S+S)/60)/60)%24;
M=(Cr.M+M+(Cr.S+S)/60)%60;
S=(Cr.S+S)%60;
}
//方法1、时钟加时、分、秒
void Clock:: TimeAdd(int h,int m,int s)
{
H=(h+H+(m+M+(s+S)/60)/60)%24;
M=(m+M+(s+S)/60)%60;
S=(s+S)%60;
}
//方法2、时钟加秒数
void Clock:: TimeAdd(int s)
{
H=(H+(M+(S+s)/60)/60)%24;
M=(M+(S+s)/60)%60;
S=(S+s)%60;
}
int main()
{
Clock C1;
Clock C2(8,20,20);
C1.TimeAdd(4000);
C1.ShowTime();
//C2.TimeAdd(&C1);
C2.TimeAdd(C1);
C2.ShowTime();
return 0;
}
三、对象数组
是以对象为元素的数组,定义格式:
类名 对象数组名[ 常量表达式];
与结构数组不同,对象数组的初始化需要使用构造函数完成,初始化格式:
数组名[n]={类名(数据成员1初值),类名(成员2初值),……}
不带初始化表的数组,其初始化靠调用不带参数的构造函数完成。
例子:计算一个班学生某门功课的成绩
#include
using namespace std;
#include
const int MaxN=100;
const double Rate=0.6;
class Score
{
private:
long No;//学号
char * Name;
int Usual;
int Final;
int Total;
public:
//带默认形参值的构造函数,可省略成员变量名
Score(long =0,char * =NULL,int =0,int =0,int =0);
void Count();
void ShowScore();
};
Score :: Score(long no,char * name,int usual,int final,int total)
{
No=no;
Name=name;
Usual=usual;
Final=final;
Total=total;
}
void Score::Count()
{
Total=Usual*Rate+Final*(1-Rate)+0.5;
}
void Score::ShowScore()
{
//setw(int n);设置域宽,包含在
cout<<No<<setw(20)<<Name<<setw(20)<<Usual<<setw(20)<<Final<<setw(20)<<Total<<endl;
}
int main()
{
Score ClassScore1[3];//不带初始化表的对象数组,调用不带参数的构造函数
Score ClassScore2[2]={
Score(2020090,"zhangsan",99,80),
Score(2020080,"lisi",100,75)
};
for(int i=0;i<2;i++)
{
ClassScore2[i].Count();//每一个对象调用函数
ClassScore2[i].ShowScore();
}
return 0;
}
四、动态对象
- 局部对象:调用函数时建立,在函数调用完成后消失;
- 全局对象:程序执行时建立,执行完成后消失;
- 动态对象:编程者随时动态建立,可随时消失的对象;
建立和删除一个动态对象:
对象指针 = new 类名(初值表);
detete 对象指针;
Clock * Cp;//建立对象指针
Cp=new Clock(0,0,0);
对象指针的类型要与类名一致,建立时要调用构造函数。
用途:用动态对象组成动态对象数组
对象指针 =new 类名 [数组大小]
delete [ ] 对象指针//删除
五、this指针
引用调用它的对象,隐含的this指针来实现,是一个系统预定义的特殊指针,指向当前对象,表示当前对象的地址,可区分本对象的数据成员与其他变量
this指针不是调用对象的名称,而是指向调用对象的指针的名称
void Clock:: SetTime(int H,int M,int S)
{//使用this指针,则形参名可与类的数据成员名一样
this->H=H;
this-M=M;
this->S=s;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)