C++ 对象和实例的区别,以及用new和不用new创建类对象区别
起初剛學(xué)C++時(shí),很不習(xí)慣用new,后來(lái)看老外的程序,發(fā)現(xiàn)幾乎都是使用new,想一想?yún)^(qū)別也不是太大,但是在大一點(diǎn)的項(xiàng)目設(shè)計(jì)中,有時(shí)候不使用new的確會(huì)帶來(lái)很多問(wèn)題。當(dāng)然這都是跟new的用法有關(guān)的。new創(chuàng)建類(lèi)對(duì)象,使用完后需使用delete刪除,跟申請(qǐng)內(nèi)存類(lèi)似。所以,new有時(shí)候又不太適合,比如在頻繁調(diào)用場(chǎng)合,使用局部new類(lèi)對(duì)象就不是個(gè)好選擇,使用全局類(lèi)對(duì)象或一個(gè)經(jīng)過(guò)初始化的全局類(lèi)指針?biāo)坪醺痈咝А?/p>
C++ 對(duì)象實(shí)例化的一些概念:C++ 如果直接定義類(lèi),如classA? a; a存在棧上(也意味著復(fù)制了對(duì)象a在棧中);如果classA? a = new classA就存在堆中。
一、new創(chuàng)建類(lèi)對(duì)象與不new區(qū)別
下面是自己總結(jié)的一些關(guān)于new創(chuàng)建類(lèi)對(duì)象特點(diǎn):
- new創(chuàng)建類(lèi)對(duì)象需要指針接收,一處初始化,多處使用
- new創(chuàng)建類(lèi)對(duì)象使用完需delete銷(xiāo)毀
- new創(chuàng)建對(duì)象直接使用堆空間,而局部不用new定義類(lèi)對(duì)象則使用棧空間
- new對(duì)象指針用途廣泛,比如作為函數(shù)返回值、函數(shù)參數(shù)等
- 頻繁調(diào)用場(chǎng)合并不適合new,就像new申請(qǐng)和釋放內(nèi)存一樣
二、new創(chuàng)建類(lèi)對(duì)象實(shí)例
1、new創(chuàng)建類(lèi)對(duì)象例子:
CTest* pTest = new CTest();
delete pTest;
pTest用來(lái)接收類(lèi)對(duì)象指針。
不用new,直接使用類(lèi)定義申明:
CTest mTest;
此種創(chuàng)建方式,使用完后不需要手動(dòng)釋放,該類(lèi)析構(gòu)函數(shù)會(huì)自動(dòng)執(zhí)行。而new申請(qǐng)的對(duì)象,則只有調(diào)用到delete時(shí)再會(huì)執(zhí)行析構(gòu)函數(shù),如果程序退出而沒(méi)有執(zhí)行delete則會(huì)造成內(nèi)存泄漏。
2、只定義類(lèi)指針
這跟不用new申明對(duì)象有很大區(qū)別,類(lèi)指針可以先行定義,但類(lèi)指針只是個(gè)通用指針,在new之前并為該類(lèi)對(duì)象分配任何內(nèi)存空間。比如:
CTest* pTest = NULL;
但使用普通方式創(chuàng)建的類(lèi)對(duì)象,在創(chuàng)建之初就已經(jīng)分配了內(nèi)存空間。而類(lèi)指針,如果未經(jīng)過(guò)對(duì)象初始化,則不需要delete釋放。
3、new對(duì)象指針作為函數(shù)參數(shù)和返回值
下面是天緣隨手寫(xiě)一個(gè)例子,不太嚴(yán)謹(jǐn)。主要示意一下類(lèi)指針對(duì)象作為返回值和參數(shù)使用。
[cpp]?view plaincopyC++對(duì)象實(shí)例化
[cpp]?view plaincopy初學(xué)Java時(shí),在很長(zhǎng)一段時(shí)間里,總覺(jué)得基本概念很模糊。后來(lái)才知道,在許多Java書(shū)中,把對(duì)象和對(duì)象的引用(實(shí)例)混為一談。
如果分不清對(duì)象與對(duì)象引用,那實(shí)在沒(méi)法很好地理解下面的面向?qū)ο蠹夹g(shù),把自己的一點(diǎn)認(rèn)識(shí)寫(xiě)下來(lái),或許能讓初學(xué)Java的朋友們少走一點(diǎn)彎路。????????
為便于說(shuō)明,我們先定義一個(gè)簡(jiǎn)單的類(lèi):??[cpp]?view plaincopy
有了這個(gè)類(lèi)(模板),就可以用它來(lái)創(chuàng)建對(duì)象:student stu1 = new? student();
通常把這條語(yǔ)句的動(dòng)作稱(chēng)之為創(chuàng)建一個(gè)對(duì)象,其實(shí),它包含了四個(gè)動(dòng)作。
1)右邊的"new? student",是以student類(lèi)為模板,在堆空間里創(chuàng)建一個(gè)student類(lèi)的對(duì)象(也簡(jiǎn)稱(chēng)為student對(duì)象)。
2)末尾的()意味著,在對(duì)象創(chuàng)建后,立即調(diào)用student類(lèi)的構(gòu)造函數(shù),對(duì)剛生成的對(duì)象進(jìn)行初始化。
??? 構(gòu)造函數(shù)是肯定有的。如果你沒(méi)寫(xiě),Java會(huì)給你補(bǔ)上一個(gè)默認(rèn)的構(gòu)造函數(shù)。
3)左邊的"student stu1"創(chuàng)建了一個(gè)student類(lèi)引用變量。所謂student類(lèi)引用,就是以后可以用來(lái)指向某個(gè)?
??? student對(duì)象的對(duì)象引用,它指向的是某個(gè)student對(duì)象的內(nèi)存地址(有點(diǎn)C語(yǔ)言中指針的味道)。
4)"="操作符使對(duì)象引用指向剛創(chuàng)建的那個(gè)student對(duì)象。
????我們可以把這條語(yǔ)句拆成兩部分:student? stu1; ??????????????? (1)
???????????????????????????????????????????????????????????? stu1 = new student();???? (2)
??? 效果是一樣的。
??? 這樣寫(xiě),就比較清楚了,有兩個(gè)實(shí)體:一是對(duì)象引用變量(stu1),在Sun公司的實(shí)現(xiàn)中,對(duì)象的引用是一個(gè)句柄,其中包含一對(duì)指針:一個(gè)指針指向該對(duì)象的方法表,一個(gè)指向該對(duì)象的數(shù)據(jù);另一個(gè)是對(duì)象本身(就是new出來(lái)的那個(gè)對(duì)象)。
????在堆空間里創(chuàng)建的實(shí)體,與在數(shù)據(jù)段以及棧空間里創(chuàng)建的實(shí)體不同。盡管它們也是確確實(shí)實(shí)存在的實(shí)體,但是,我們看不見(jiàn),也摸不著。不僅如此,我們仔細(xì)研究一下第二句,想想剛剛創(chuàng)建的student對(duì)象叫什么名字?
??? 有人說(shuō),它叫"student"。不對(duì),"student"是類(lèi)(對(duì)象的創(chuàng)建模板)的名字。一個(gè)student類(lèi)可以據(jù)此創(chuàng)建出無(wú)數(shù)個(gè)對(duì)象,這些對(duì)象不可能全叫"student"。對(duì)象連名都沒(méi)有,沒(méi)法直接訪問(wèn)它。我們只能通過(guò)對(duì)象引用(實(shí)例)來(lái)間接訪問(wèn)對(duì)象。
????為了形象地說(shuō)明對(duì)象、對(duì)象引用及它們之間的關(guān)系,可以做一個(gè)或許不很妥當(dāng)?shù)谋扔?#xff1a;
????對(duì)象好比是一只沒(méi)有線的風(fēng)箏,引用變量是一根線,可以用來(lái)系風(fēng)箏。如果只執(zhí)行了第一條語(yǔ)句,還沒(méi)執(zhí)行第二條,此時(shí)創(chuàng)建的引用變量stu1還沒(méi)指向任何一個(gè)對(duì)象,它的值是null,引用變量可以指向某個(gè)對(duì)象,或者為null。這時(shí)stu1是一根線,一根還沒(méi)有系上任何一個(gè)風(fēng)箏的線。
???執(zhí)行了第二句后,一只新風(fēng)箏做出來(lái)了,并被系在stu1這根線上。我們抓住這根線,就等于抓住了那只風(fēng)箏。
???再來(lái)一句:student? stu2;就又做了一根線,還沒(méi)系上風(fēng)箏。如果再加一句:stu2=stu1;系上風(fēng)箏了。
???這里,發(fā)生了復(fù)制行為。但是,要說(shuō)明的是,對(duì)象本身并沒(méi)有被復(fù)制,被復(fù)制的只是對(duì)象引用。
???結(jié)果是,stu2也指向了stu1所指向的對(duì)象,也就是兩根線系的是同一只風(fēng)箏。
???如果用下句再創(chuàng)建一個(gè)對(duì)象:stu2=newstudent();則引用變量stu2改指向第二個(gè)對(duì)象。
?? 從以上敘述再推演下去,我們可以獲得以下結(jié)論:
?? (1)一個(gè)對(duì)象引用可以指向0個(gè)或1個(gè)對(duì)象(一根線可以不系風(fēng)箏,也可以系一個(gè)風(fēng)箏),而且可以改指;
?? (2)一個(gè)對(duì)象可以有N個(gè)引用指向它(可以有N條線系同一個(gè)風(fēng)箏)。
??? 如果有下面語(yǔ)句:stu1=stu2;
????按上面的推斷,stu1也指向了第二個(gè)對(duì)象。這個(gè)沒(méi)問(wèn)題。問(wèn)題是第一個(gè)對(duì)象呢?沒(méi)有一條線系住它,它飛了。
??? 很多書(shū)里說(shuō),它被Java的垃圾回收機(jī)制回收了,這不確切,準(zhǔn)確地說(shuō),它已成為Java垃圾回收機(jī)制的處理對(duì)象。至于什么時(shí)候真正被回收,那要看垃圾回收機(jī)制的心情了。由此看來(lái),new? student();該語(yǔ)句應(yīng)該不合法吧,至少是沒(méi)用的吧?不對(duì),它是合法的,而且可用的。譬如,如果我們僅僅為了打印而生成一個(gè)對(duì)象,就不需要用引用變量來(lái)系住它。最常見(jiàn)的就是打印字符串:System.out.println("Iam Java!");
??? 字符串對(duì)象"I amJava!"在打印后即被丟棄,有人把這種對(duì)象稱(chēng)之為臨時(shí)對(duì)象。
最后再說(shuō)明一下:
C++中:
Student? student(20) ;??//這里student是引用 對(duì)象分配在 棧空間中,這里只是我的理解
Student *student = new? Student(20); ?//這里student是指針,new Student(20)是分配在堆內(nèi)存空間的
但是在Java中Student? student(20) ; ?//注意:java中沒(méi)有這樣實(shí)例化對(duì)象的, 要想得到一個(gè)對(duì)象 必須要new出來(lái).
Student student ;?//這個(gè)只是定義了一個(gè)引用?,沒(méi)有指向任何對(duì)象
Student student = new Student(20);???//定義了一個(gè)引用,指向堆內(nèi)存中的student對(duì)象
總結(jié)
以上是生活随笔為你收集整理的C++ 对象和实例的区别,以及用new和不用new创建类对象区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++创建对象的两种方式
- 下一篇: 一个Lex/Yacc完整的示例(可使用C