关于类与对象的进一步讨论.docx

上传人:b****4 文档编号:3136970 上传时间:2022-11-17 格式:DOCX 页数:19 大小:21.41KB
下载 相关 举报
关于类与对象的进一步讨论.docx_第1页
第1页 / 共19页
关于类与对象的进一步讨论.docx_第2页
第2页 / 共19页
关于类与对象的进一步讨论.docx_第3页
第3页 / 共19页
关于类与对象的进一步讨论.docx_第4页
第4页 / 共19页
关于类与对象的进一步讨论.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

关于类与对象的进一步讨论.docx

《关于类与对象的进一步讨论.docx》由会员分享,可在线阅读,更多相关《关于类与对象的进一步讨论.docx(19页珍藏版)》请在冰豆网上搜索。

关于类与对象的进一步讨论.docx

关于类与对象的进一步讨论

第3章关于类和对象的进一步讨论

请注意,这一章内容是C++的重点,要专门注意!

第2章咱们介绍了关于类的一些大体内容,关于类对象的数据成员的初始化咱们始终是通过成立成员函数来实现的。

如:

类Time确实是通过set_time那个成员函数来实现的。

而且一样都是用赋值语句给数据成员赋值,或通过cin来为数据成员从键盘输入值来实现。

然后手工挪用该函数对数据成员进行赋值的。

3Boxbox1Boxbox2rint();

}Boxbox1#include

usingnamespacestd;

classBox

{

public:

Box(inth=10,intw=10,intl=10):

height(h),width(w),length(l){}

intvolume();

private:

intheight,width,length;

};

intBox:

:

volume()

{

returnheight*width*length;

}

intmain()

{

Boxbox1;

cout<<()<

Boxbox2(15);

cout<<()<

Boxbox3(15,20);

cout<<()<

Boxbox4(15,20,30);

cout<<()<

}

在构造函数中利用默许参数是方便有效的,这相当于提供了多个重载的构造函数。

说明:

(1)构造函数的默许值要在声明中指定。

(2)声明时能够省略形参名,如:

Box(int=10,int=10,int=10);

(3)当构造函数的参数全数指定为默许值时,能够给出一个或多个参数,也能够不给参数,这时就不能再概念重载构造函数了。

_str());_str());

day=atoi(8,2).c_str());

}2005-12-28<

}

~Student()

{cout<<"Destructorcalled."<

voiddisplay()

{cout<<"num:

"<

cout<<"name:

"<

cout<<"sex:

"<

}

private:

intnum;

stringname;

charsex;

};

intmain()

{Studentstud1(10010,"Wang_li",'f');

();

Studentstud2(10011,"Zhang_fun",'m');

();

return0;

}

运行结果为:

Constructorcalled.

num:

10010

name:

Wang_li

sex:

f

Constructorcalled.

num:

10011

name:

Zhang_fun

sex:

m

Destructor

Destructor

挪用构造函数和析构函数的顺序

从例的结果能够明白:

先构造的后析构,后构造的先析构。

在一个大程序中,各类作用域的对象很多,有些对象包括在别的对象里面,有些对象早在主函数开始运行之前就已经成立。

创建对象的唯一途径是挪用构造函数。

构造函数是一段程序,因此构造对象的前后顺序不同,直接阻碍程序执行的前后顺序,致使不同的运行结果。

C++给构造对象的顺序作了专门的规定。

一、局部对象

当程序执行到局部对象的概念的地方时,挪用构造函数创建该对象;当程序退出概念该对象所在的函数体时,挪用析构函数释放该对象。

二、静态对象

当程序第一次执行到静态对象的概念的地方时,挪用构造函数创建该对象;当程序终止时挪用析构函数释放该对象。

三、全局对象

当程序开始执行时,挪用构造函数创建该对象;当程序终止时挪用析构函数释放该对象。

和全局变量一样,所有全局对象在主函数开始运行之前,全数已被构造。

因为构造进程是程序语句的执行进程,因此这会给调试带来问题。

当要开始调试时,所有全局对象的构造函数都已被执行,若是它们中的一个有致命错误,那么你可能永久也得不到操纵权。

这种情形下,该程序在它开始执行之前就死机了。

有两种方式能够解决那个问题:

一是将全局对象先作为局部对象来调试;二是在所有疑心有错的构造函数的开头,增加输出语句,如此在程序开始调试时,你能够看到来自这些对象的输出信息。

全局对象不像局部对象的构造顺序那么简单,全局对象是没有如此的操纵流向来指明其顺序的。

关于简单应用的单文件程序来讲,全局对象能够依照它们显现的顺序依次进行构造。

可是,单文件程序只是出此刻实验室或教室里,真正有效的程序都是由多个文件组成的,这些文件被别离编译、连接。

因为编译器不能操纵文件的连接顺序,因此它不能决定不同文件中全局对象之间的构造顺序。

一旦main函数开始启动,那么运行顺序是可控,但全局对象并非依托于从main函数以后的顺序,它早在main运行之前就创建完毕了。

因此全局对象的创建顺序在标准C++中没有规定,也无法规定,一切视编译器的内在特性而定。

下面通过一个实例来看不同对象的作用域和生命期

"<

}

~Student()

{cout<<"Destructorcalled."<

voiddisplay()

{cout<<"num:

"<

}

private:

intnum;

};

intmain()

{

Studentstud[5]={1,2,3,4,5};

return0;

}

运行结果:

Constructorcalled.1

Constructorcalled.2

Constructorcalled.3

Constructorcalled.4

Constructorcalled.5

Destructor

Destructor

Destructor

Destructor

Destructor

Pressanykeytocontinue

若是构造函数有多个参数,那么不能用在概念数组时直接提供所有实参的方式,因为一个数组有多个元素,对每一个元素要提供多个实参,若是再考虑到构造函数有默许参数的情形,很容易造成实参与形参的对应关系不确信,显现二义性。

那么,在概念对象数组时应当如何实现初始化呢?

看下例:

#include

#include

usingnamespacestd;

classStudent

{public:

Student(intn,stringnam,chars)

{num=n;

name=nam;

sex=s;

cout<<"Constructorcalled."<

}

~Student()

{cout<<"Destructorcalled."<

voiddisplay()

{cout<<"num:

"<

cout<<"name:

"<

cout<<"sex:

"<

}

private:

intnum;

stringname;

charsex;

};

intmain()

{

StudentStud[3]={Student(1001,"wang",'f'),Student(1002,"li",'m'),Student(1003,"zhang",'f')};

return0;

}

运行结果:

Constructorcalled.1001

Destructor

Constructorcalled.1002

Destructor

Constructorcalled.1003

Destructor

Destructor

Destructor

Destructor

再来看一下书中P82例

#include

usingnamespacestd;

classBox

{public:

Box(inth=10,intw=12,intlen=15):

height(h),width(w),length(len){}

intvolume();

~Box()

{cout<<"析构"<

private:

intheight;

intwidth;

intlength;

};

intBox:

:

volume()

{return(height*width*length);}

intmain()

{

Boxa[3]={Box(),Box(15,18,20),Box(16,20,26)};

cout<<"volumeofa[0]is"<

cout<<"volumeofa[0]is"<

cout<<"volumeofa[0]is"<

return0;

}

volumeofa[0]is1800

volumeofa[0]is5400

volumeofa[0]is8320

析构162026

析构151820

析构101215

 

3.5对象指针

指向对象的指针

对象空间的起始地址确实是对象的指针,能够概念一个指针变量,用来寄存对象的指针。

若是有一个类:

#include

usingnamespacestd;

classTime

{

public:

inthour,minute,sec;

Time(int,int,int);

voidget_time();

};

Time:

:

Time(inth,intm,ints)

{

hour=h;minute=m,sec=s;

}

voidTime:

:

get_time()

{

cout<

"<

"<

}

intmain()

{

Time*pt;et_time();p)();

return0;

}

从上例能够明白,概念指向类中成员函数的指针一样形式如下:

返回类型名(类名:

:

指针变量名)(参数列表)

概念好后,就能够够把成员函数名赋值给指针变量名了。

指针变量名=&类名:

:

成员函数名

this指针

在第二章提到过,每一个对象中的数据成员都别离占有存储空间,若是对同一个类概念了n个对象,那么有n组一样大小的空间以寄存n个对象中的数据成员。

可是,不同的对象都挪用同一个函数代码段。

那么,当不同对象的成员函数相用数据成员时,怎么能保证引用的是所指定的对象的数据成员呢?

事实上是每一个成员函数中都包括一个特殊指针,那个指针的名字确实是this。

#include

usingnamespacestd;

classTime

{

public:

Time(int,int,int);

voidget_time();

pri

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1