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