亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++中實現Java的存儲管理機制

2019-11-17 05:07:18
字體:
來源:轉載
供稿:網友


  眾所周知,java語言最明顯的優勢在于用它設計的程序可以廣泛地運行于互聯網上所有安裝了VM解釋器的計算機上。然而,如今JAVA之所以在市場上如此流行,還得益于它的另一賣點:它提供了安全可靠和使用方便的存儲治理機制。這是部分編程人員將它與其前身C++語言對比后所得出的結論。本文將針對兩種語言的內存(以對象為單位)使用機制,通過從靈活性、易用性和效率三個方面的比較,來證實這樣一個事實:在C++中可以實現與JAVA一樣的存儲治理機制。

  一、JAVA對象是C++對象和指針二者的繼續

  JAVA作為C++的后繼,在內存分配和對象使用上與之有很大的相似之處。請看下面的比較:

  表1

操作JAVAC++指針使用非指針使用聲明ObjectClass InstanceObjectClass* InstanceObjectClass Instance創建Instance=new ObjectClass()Instance=new ObjectClass()聲明時自動創建數據訪問Instance.DataInstance->DataInstance.Data方法調用Instance.Method()Instance->Method()Instance.Method()復制指針復制Instance1=Instance2Instance1=Instance2
不提供內容復制由類自身定義不提供 缺省,或由類自身定義比較指針比較Instance1==Instance2Instance1==Instance2 不提供內容比較由類自身定義不提供缺省,或由類自身定義銷毀不再引用時由垃圾收集器自動銷毀delete Instance超出作用域時自動銷毀
  注:

 ?、?C++的"指針使用"一列中并未列出形如*Instance的使用,因為這樣做的實質不是指針使用;

 ?、?指針復制"是指使得兩個對象今后使用相同的一塊內存區域,任何對此區域的修改同時會反映到這兩個對象上;

 ?、?內容復制"則指拷貝兩個對象各自的存儲區域,拷貝后內容相同,但各自保留自己的存儲區,以后對任一者的修改不會影響另一者。

  從上表可以看出,除了對象銷毀機制以外,JAVA的對象其實是從C++中的對象和指針共同繼續而來的。
但是,很多極力提倡JAVA語言的人似乎沒有意識到這種關系。他們批評C++指針的概念太難被初學者接受。的確,對初學者來說,接受計算機存儲器和指針的概念并不是輕而易舉的事。事實上,很多程序員都經歷過這樣一個迷惘的階段。但這并不意味著存在一種對存儲器的解釋可以完全避免"指針"這一概念--在JAVA語言中也是如此?,F在有很多講解JAVA語言的教材,但真正能夠從頭到尾不出現"指針"或者類似概念(不包括抨擊C++語言時的使用)的,又有幾本呢?

  非凡地,JAVA初學者由于理解的障礙,經常提出像這樣的問題:"為什么像int、float這樣的變量使用前不需要先用new命令來創建而對象卻要呢?為什么兩個對象互相復制以后,修改其中一個會影響另一個,而像int、float這樣的基本數據類型卻不會呢?兩個值相等的對象,用==比較的結果為什么是false,它們有什么是不等呢……"面對這樣的問題,即使許多對JAVA比較熟悉的人有時也說不出個所以然來。究其原因,就是JAVA中的對象從來就沒有離開C++指針的影子,非凡是在創建、復制(事實上,JAVA默認時只提供指針復制)和比較等最常用的操作上。因而使用它們就必須遵循指針的規則,否則將無法為計算機或編程者所理解。在C++中,指針和對象其實是與int、float共通的數據類型,但又各有其特性;繼續到JAVA中以后,二者的特性互相糅合而融為一體,因此對其含義的問題就產生模棱兩可的解釋:JAVA對象有時是對象,有時是指針,但大多數時候是指針。

  對C++指針的另一種批評指出,C++答應指針指向任意內存區域,因此輕易引起系統的干擾,即使很有經驗的程序員在使用時也難免產生疏忽。這種批評不無道理,因為大部分C++程序出錯的原因都與指針有關。但由此而批評指針存在的價值是不對的。沒有C++程序員愿意從不使用指針。指針是程序設計的一樣利器,凡涉及內存的操作,沒有指針不能做到的,并且它的效率比其他任何替代方法都高。這就是眾多C++程序員寧愿冒著高度的出錯風險也堅持使用指針的最大原因,而并不是他們無法避免使用指針。假如真正要像JAVA語言那樣刻意避免指針的話,筆者在后面可以證實,只要他們愿意,在C++程序員同樣可以做到,而且性能比JAVA更好。他們可以設計一類徹頭徹尾的C++對象,而他們的使用方法卻與JAVA對象一摸一樣!這恐怕是許多JAVA崇拜者所始料不及的。

  本文后面所附的程序,為用戶營造了這樣一個編程環境:只涉及對象使用;避免指針禍害,但卻保持像指針一樣快速高效地訪問內存的優點;像JAVA所倡導的那樣,不須操心對象釋放問題,在不再引用時由系統自動清理。必須強調的是,盡管該程序段理想地模擬出了JAVA的存儲使用環境,編程者卻確確實實在使用C++語言,并不會因此失去C++語言所具備的其他一切高效特性,甚至可以繼續使用其他的指針。

更多文章 更多內容請看網絡治理實用手冊專題,或


  二、Agent類:用C++指針模擬JAVA對象

  為了更好的說明C++與JAVA的相似之處,筆者建立了Agent類。它通過把一個特定對象類型的指針作為自己的保護成員,來實現對C++指針的包裝。


  任何使用Agent類模擬JAVA的程序必須通過如下表所示的方法來使用對象:

  表2

操作JAVA使用Agent后的C++聲明 ObjectClass InstanceAgent<ObjectClass> Instance創建Instance=new ObjectClass() Instance=new Agent<ObjectClass>數據訪問Instance.Data Instance().Data方法調用Instance.Method() Instance().Method()復制 指針復制Instance1=Instance2內容復制由類自身定義比較指針比較Instance1==Instance2內容比較由類自身定義銷毀不需要,由程序內部自動治理
  上表顯示了兩種對象在使用上的驚人的相似性。本質上,兩種對象是一樣的,因為JAVA解釋器本身就是使用與Agent相似的實現方法。但有些形式上的相似性事實上是無法做到的,因為它們究竟屬于兩種不同的語言,必須依照各自的規定。以下是兩種需要注重的形式上的差別:在C++中,

  1、 象所屬類的名稱(如ObjectClass)必須放在Agent后,用〈 〉包括起來(否則,該類將與本文所討論的Agent類毫無關系);

  2、 對象本身數據的訪問和方法的調用必須在對象表識符后加一對括號,如Instance().Method(),因為Agent重定義了操作符Operator (),以幫助編譯器將一個Agent的實例(如Instance)解釋成用戶所使用的具體某一個類(如ObjectClass)的實例,而Instance().Method()這一調用本身也等價于((ObjectClass&)Instance).Method()。

  另外,任一使用了Agent的程序必須在首部加入#include "Agent.h"才能實現對它的訪問。

  以下為包含類Agent全部定義的C++頭文件。由于該文件篇幅較小,所有Agent的方法均采用內聯函數的形式定義。

#ifndef OBJECT_AGENT_CLASS
#define OBJECT_AGENT_CLASS

#define null 0

template<class ObjectType>
class Agent
{
int *Reference;
static bool bNewOperation;

PRotected:

ObjectType *Marrow;
void Finalize()
{
if (Reference)
{
(*Reference)--;
if (Marrow)
{
if (*Reference<=0 && Marrow)
{
delete Marrow;
delete Reference;
}
Marrow=null;
}
Reference=null;
}
}

public:

// constrUCtors
Agent()
{
if (bNewOperation)
{
Marrow=new ObjectType;
Reference=new int;
*Reference=1;
bNewOperation=false;
}
else
{
Marrow=null;
Reference=null;
}
}

Agent(ObjectType obj)
{
Marrow=new ObjectType;
Reference=new int;
*Reference=1;
*Marrow=obj;
}

// destructor
~Agent() { Finalize(); }

// convertions
operator ObjectType&() { return *Marrow; }

// operators
Agent<ObjectType>& operator=(Agent<ObjectType> obj)
{
Finalize();
Marrow=obj.Marrow;
Reference=obj.Reference;
(*Reference)++;
return *this;
}

Agent<ObjectType>& operator=(Agent<ObjectType>* obj)
{
Finalize();
if (obj)
{
Marrow=obj->Marrow;
Reference=obj->Reference;
}
return *this;
}

bool operator ==(Agent<ObjectType> obj) const
{
return Marrow==obj.Marrow;
}

bool operator !=(Agent<ObjectType> obj) const
{
return Marrow!=obj.Marrow;
}

ObjectType& operator ()() { return *Marrow; }

void *operator new(size_t size)
{
bNewOperation=true;
return new char[size];
}
};

template<class ObjectType> bool Agent<ObjectType>::bNewOperation=false;

#endif

  從源程序中可以看出,Agent類實際上是一個模版(template)。這樣做的好處是,用戶不必為包容自己不同類型的對象而定義之相對應的Agent類。


  Agent類的工作原理是這樣的:

  當用戶使用Agent<ObjectClass>來定義對象的類型時,他事實上定義的是一個Agent類型的對象。編譯器自動為該對象產生一個類型為ObjectClass*,名為Marrow的成員,而ObjectClass* Agent::Marrow才真正代表用戶將要建立的對象。整型成員Reference記錄當前對此對象的Marrow的引用個數,當降為0時自動消除Marrow,即銷毀用戶定義的ObjectClass實例。當用戶調用Instance=new Agent<ObjectClass>來創建對象時,分配Marrow,Reference置1,對象處于可使用狀態。兩個Agent實例互相賦值時,重定義的操作符operator =協助復制Marrow指針,更改公共的Reference成員,使之指示正確的引用計數。還有一個必須注重的靜態成員:bNewOperation。它是一個布爾(真假值)類型的變量。當程序員用Agent<ObjectClass> Instance來定義對象時,其值為false,指出不需要真正建立Agent::Marrow的實例,因而Marrow將被賦值為null;當用Instance=new Agent<ObjectClass>來創建對象實例時,其值為true,提示構造函數建立相應Marrow的實例。其控制通過操作符operator new實現。而操作符operator ()則使得,當調用Instance()時,編譯器自動返回ObjectClass類型的*Marrow,所以調用用戶所需的對象成員可以使用Instance().Data和Instance().Method()。

更多文章 更多內容請看網絡治理實用手冊專題,或
  三、應用例子

  下面的JAVA與C++例子程序執行同樣的操作:建立100000個xy類型的對象,保存到一個對象數組中,釋放內存廢區,如此重復10次,在結束時顯示各自運行的時間。這個例子可以幫助讀者了解兩種語言的差異。

  1、JAVA程序如下:

public class xy //一個簡單的數據類
{
int x, y;
}

public class TestTime {
static int OBJECTS=100000;
static int CHECKTIMES=10;
public static void main(String[] args) {
xy[] obj=new xy[OBJECTS];
long start, end;
long total=0, max=0, min=OBJECTS*CHECKTIMES, time;
System.out.print("PROGRESS: ");
for (int j=0;j<CHECKTIMES;j++) {
System.out.print(".");
start=System.currentTimeMillis();
for (int i=0;i<OBJECTS;i++) obj[i]=new xy();
if (j>0) System.gc(); //從第二次循環開始強制回收內存廢區
end=System.currentTimeMillis();
time=end-start;
total+=time;
if (time<min) min=time;
if (time>max) max=time;
}
System.out.print("FINISHED!/r/n Minimum time in 1 check: "+min+" Milliseconds");
System.out.print("/r/n Maximum time in 1 check: "+max+" Milliseconds");
System.out.print("/r/n Average time in 1 check: "+total/CHECKTIMES+" Milliseconds");
System.out.print("/r/n Total time in "+CHECKTIMES+" checks: "+total+" Milliseconds");
}
}
  2、使用Agent類后的C++程序:

#include "stdio.h"
#include "time.h"
#include "Agent.h"

#define OBJECTS 100000
#define CHECKTIMES 10

class xy //一個簡單的數據類
{
int x,y;
};

void main() {
Agent<xy> obj[OBJECTS]; //數組自動創建,不須使用new
clock_t start, end;
unsigned long total=0, max=0, min=-1, time;
printf("PROGRESS: ");
for (int j=0;j<CHECKTIMES;j++) {
printf(".");
start=clock();
for (int i=0;i<OBJECTS;i++)
obj[i]=new Agent<xy>; //operator new和構造函數被調用,創建Marrow
//對象被重新賦值時自動釋放,不須像System.gc()這樣的語句強制實施
end=clock();
time=(end-start)*1000/CLOCKS_PER_SEC;
total+=time;
if (time<min) min=time;
if (time>max) max=time;
}
printf("FINISHED!/r/n Minimum time in 1 check: %d Milliseconds", min);
printf("/r/n Maximum time in 1 check: %d Milliseconds", max);
printf("/r/n Average time in 1 check: %d Milliseconds", total/CHECKTIMES);

printf("/r/n Total time in %d checks: %d Milliseconds", CHECKTIMES, total);
}
  程序運行結果:



更多文章 更多內容請看網絡治理實用手冊專題,或   四、程序結果的分析與比較

  以下從靈活性、易用性和效率三方面對JAVA中的對象和使用Agent以后的C++對象的使用情況進行分析和比較。

  1、靈活性

  由于Agent類直接包含了C++的對象指針Marrow,所以任何C++的指針操作均可應用于Agent類上。從它派生出來的任何子類都可以對這一受保護的對象指針實施所需要的操作,使得用戶獲得了最大限度的靈活性。但就Agent本身而言,并不答應外部程序訪問Marrow,故不存在很多人擔心的指針誤用的問題,因而是安全的。此外,這樣做把對象的治理和使用分開來。就是說,譬如有對象Agent<ObjectClass> Instance,則Instance.Method ()指調用對象中屬于Agent類的對所有對象類型均適用的方法(如存儲治理、對象數據維護等功能,用戶可以在Agent的派生類中自行添加),而Instance().Method()則調用屬于ObjectClass本身用于實施具體操作的成員(對于繪圖類的繪圖操作、打印類的打印操作等等)。通過這種方法,有需要的程序員可以參與系統內部的對象治理機制,而一般的編程者則可以避免誤用指針的煩惱。這種C++特有的靈活性和適應性是JAVA所不能具備的。

  2、易用性

  使用Agent類與JAVA的主要區別僅在于上文列舉的兩處形式上的不同點。對Agent不作任何繼續和更改的情況下,程序員可以像正在使用JAVA那樣,不須關心內存分配和清理,不須深入了解指針的概念,依照JAVA的步驟來使用對象。所以二者在此方面相當。

  3、運行效率

  這是大多數程序員最關心的。下面有兩組測試數據,分別是上述例子C++程序(使用Microsoft Visual C++ 6.0編譯運行)與JAVA程序(分別運行于IBM VisualAge for JAVA 3.0和Borland J Builder 3.0下)在兩臺不同型號的計算機上的運行結果,使用的操作系統為 Microsoft Windows 98,且保證測試過程中沒有出現影響結果準確性的明顯讀磁盤現象。從表中的數據可以很清楚地看到,使用Agent類之后,C++的程序仍然比JAVA程序快很多。這是由于編譯型語言對于解釋型語言在速度上具有一貫的優勢;另外, C++程序并不需要創建一個獨立的線程來治理資源,因此其運行開銷比JAVA更小。

  表3

計算機配置VisualAge for JAVA 3.0JBuilder 3.0使用Agent后Visual C++ 6.0最小運行時間(ms)最大運行時間(ms) 平均運行時間(ms)總共運行時間(ms)最小運行時間(ms)最大運行時間(ms)平均運行時間(ms) 總共運行時間(ms)最小運行時間(ms)最大運行時間(ms)平均運行時間(ms) 總共運行時間(ms)Duron 700
128M RAM13352008 1512 15122 220 270 225 2250110 170 143 1430Celeron 333
64M RAM 2504 49883778 37784440 550 466 4660 160 280 258 2580
  從這三方面比較可以看出,在對象使用上,JAVA的表現并不如預期的理想,而C++亦并不如JAVA廣告中所指出的那么差強人意。JAVA摒棄指針使用的根本原因就在于JAVA必須實現其跨平臺使用的優點。雖然,JAVA的任何缺點都不能掩蓋這個優點,然而,為了實現這個其他眾多語言都不可能達到的優點,它作出了巨大的犧牲:假如網絡計算機上任一塊內存都可以被遠程程序訪問的話,網絡的安全性和穩定性就無法保障。放棄指針和代理內存的分配和回收等等措施的產生,很大程度上是由于把這些操作留給用戶實在不適應網絡編程的要求。出于類似的考慮,除了內存資源以外,JAVA解釋器也為用戶代管了大多數的計算機資源。因此,與其說這些是設計者們精心改良的成果,不如說是設計者們為了適應網絡特性而采取的折中。而這種折中正是JAVA作為一門新興網絡語言得以生存的要害因素。

  五、結論

  JAVA雖然流行,但并不代表它任何創新的方面都是值得吹噓的;C++成形雖然已經十年,但是它的優越性并未被軟件業發展的潮流所沖垮,C++程序員不必對之失去信心:任何問題都應該全面地、辯證地看待。

更多文章 更多內容請看網絡治理實用手冊專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲区在线播放| 91精品久久久久久综合乱菊| 国产精品jizz在线观看麻豆| 国内精品视频一区| 黄色一区二区在线观看| 懂色aⅴ精品一区二区三区蜜月| 国产美女精品视频| 国产精品美女av| 国产精品色午夜在线观看| 91精品国产高清自在线看超| 中文字幕亚洲欧美| 欧美日韩一区二区三区在线免费观看| 国产精品电影观看| 精品毛片三在线观看| 色偷偷88888欧美精品久久久| 欧美另类69精品久久久久9999| 中文字幕一区电影| 成人久久久久爱| 国产精品久久久久久av福利| 1769国内精品视频在线播放| 国产精品九九九| 精品免费在线观看| 草民午夜欧美限制a级福利片| 91午夜理伦私人影院| 国产丝袜视频一区| 久久韩剧网电视剧| 91美女片黄在线观看游戏| 久久久精品影院| 久久精品中文字幕电影| www.日韩免费| 91香蕉亚洲精品| 国产欧美一区二区白浆黑人| 91精品国产91久久久久久不卡| 国产精品视频一区二区高潮| 91精品久久久久久久久久久久久久| 日韩大片在线观看视频| 亚洲国产欧美在线成人app| 日韩电影免费在线观看中文字幕| 亚洲精品wwwww| 国产91精品网站| 97久久伊人激情网| 久久精品国产免费观看| 欧美一区二粉嫩精品国产一线天| 一本一本久久a久久精品综合小说| 98精品国产高清在线xxxx天堂| 色综合男人天堂| 色悠久久久久综合先锋影音下载| 亚洲欧美国产精品va在线观看| 在线观看日韩欧美| 国产精选久久久久久| 欧美老少做受xxxx高潮| 久久久久亚洲精品国产| 日韩视频第一页| 欧美精品免费播放| 欧美日韩第一视频| 国产精品美女av| 亚洲精品99久久久久中文字幕| 欧美激情视频在线观看| 欧美中文字幕在线观看| 久久成人在线视频| 91精品视频在线免费观看| 亚洲人成电影在线播放| 欧美在线激情视频| 日韩免费观看在线观看| 亚洲在线视频观看| 日韩不卡中文字幕| 精品亚洲夜色av98在线观看| 97精品一区二区视频在线观看| 黄色成人在线播放| 国产在线拍揄自揄视频不卡99| 国产精品久久久久影院日本| 91国内免费在线视频| 中文字幕久精品免费视频| 久久人人爽人人爽人人片av高请| 久久久精品免费| 久久久久久亚洲精品中文字幕| 欧美亚洲国产日韩2020| 一区二区三区在线播放欧美| 正在播放国产一区| 欧美成人第一页| xxav国产精品美女主播| 亚洲午夜女主播在线直播| 国产综合色香蕉精品| 国产成人精品视频在线观看| 成人做爰www免费看视频网站| 亚洲福利在线播放| 国产欧美一区二区三区四区| 国产精品男人的天堂| 欧美日韩国产一区在线| 亚洲男人的天堂在线| 亚洲美女www午夜| 国产精品久久久久久影视| 国产不卡av在线免费观看| 久久影视电视剧免费网站清宫辞电视| 欧美理论电影网| 久99久在线视频| 亚洲人精品午夜在线观看| 国产精品极品美女在线观看免费| 久久精品视频一| 成人免费在线视频网址| 亚洲xxxx18| 国产精品在线看| 国产精品视频网| 黑人精品xxx一区一二区| 国产精品福利久久久| 久久不射热爱视频精品| 久久夜精品va视频免费观看| 国产精品久久久久久一区二区| 日韩高清av一区二区三区| 国产精品视频白浆免费视频| 亚洲va电影大全| 日韩影视在线观看| 欧美激情在线狂野欧美精品| 国产91成人在在线播放| 精品久久久香蕉免费精品视频| 国产精品三级美女白浆呻吟| 热99精品只有里视频精品| 国产精品视频xxxx| 久久夜色撩人精品| 日韩欧美在线字幕| 国产精品自拍小视频| 亚洲最大福利视频网站| 亚洲精品天天看| 国产精品精品一区二区三区午夜版| 欧美精品video| 成人激情电影一区二区| 中文字幕av一区二区三区谷原希美| 55夜色66夜色国产精品视频| 亚洲精美色品网站| 92福利视频午夜1000合集在线观看| 国产精品91久久久| 欧美日韩国产二区| 国产精品成人v| 欧美亚洲日本网站| 狠狠久久亚洲欧美专区| 欧美成人精品在线播放| 精品国产一区二区三区久久久| 狠狠躁夜夜躁久久躁别揉| 欧美精品videosex牲欧美| 欧亚精品中文字幕| 91免费在线视频网站| 欧美综合在线第二页| 久久97精品久久久久久久不卡| 日韩av观看网址| 欧美伦理91i| 亚洲第一页中文字幕| 欧美高清激情视频| 国产精品免费久久久久久| 91av在线视频观看| 亚洲精品影视在线观看| 欧美视频在线观看免费| 日日狠狠久久偷偷四色综合免费| 日韩欧美国产一区二区| 国产一区二区久久精品| 最新日韩中文字幕| 日本高清+成人网在线观看| 国产视频久久久久| 日韩精品一区二区三区第95| 国产精品人成电影在线观看| 日韩视频精品在线| 性色av一区二区三区| 亚洲网站在线观看| 欧美大学生性色视频| 亚洲3p在线观看|