日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

C++ 对象和实例的区别,以及用new和不用new创建类对象区别

發(fā)布時(shí)間:2024/4/18 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 对象和实例的区别,以及用new和不用new创建类对象区别 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

起初剛學(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 plaincopy
  • class?CTest?{??public:???int?a;??};??????
  • class?CBest?{??public:???int?b;??};??????
  • CTest*?fun(CBest*?pBest)?{????
  • ???????????????????????????CTest*?pTest?=?new?CTest();?????
  • ???????????????????????????pTest->a?=?pBest->b;???return?pTest;????
  • }??????
  • int?main()?{????
  • ?????????????CBest*?pBest?=?new?CBest();?????
  • ?????????????CTest*?pRes=?fun(pBest);????????
  • ?????????????if(pBest!=NULL)??????
  • ?????????????delete?pBest;?????
  • ?????????????if(pRes!=NULL)??????
  • ?????????????delete?pRes?;?????
  • ?????????????return?0;????
  • }??
  • C++對(duì)象實(shí)例化

    [cpp]?view plaincopy
  • JAVA:??
  • A?a?=?new?A();??
  • 為A對(duì)象創(chuàng)建了一個(gè)實(shí)例,但在內(nèi)存中開(kāi)辟了兩塊空間:一塊空間在堆區(qū),存放new?A()這個(gè)對(duì)象;??
  • 另一塊空間在堆棧,也就是棧,存放a,a的值為new?A()這個(gè)對(duì)象的內(nèi)存地址。因?yàn)閖ava在JVM中運(yùn)行,??
  • 所以a?描述的內(nèi)存地址不一定是這個(gè)對(duì)象真實(shí)內(nèi)存的地址。??
  • ??
  • Object?o;?//?這是聲明一個(gè)引用,它的類(lèi)型是Object,他的值為null,還沒(méi)有指向任何對(duì)象,該引用放在內(nèi)存的棧區(qū)域中。??
  • ??
  • o?=?new?Object();?//?new?Object()句,實(shí)例化了一個(gè)對(duì)象,就是在堆中申請(qǐng)了一塊連續(xù)空間用來(lái)存放該對(duì)象。??
  • =?//?運(yùn)算符,將引向o指向了對(duì)象。也就是說(shuō)將棧中表示引用o的內(nèi)存地址的內(nèi)容改寫(xiě)成了Object對(duì)象在堆中的地址。??
  • ??
  • C++:??
  • C++?如果直接定義類(lèi),如classA?a;?a?存在棧上(也意味著復(fù)制了對(duì)象a在棧中),如果classA?a?=?new?classA就存在堆中。??
  • 初學(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
  • class?student??
  • {??
  • ??????int?name;??
  • ??????int?age;??
  • ??????int?sex;??
  • }??
  • 有了這個(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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。