蘋(píng)果的Objective-C編譯器批準(zhǔn)用戶在統(tǒng)一個(gè)源文件里自由地混雜利用C++和Objective-C蔬胯,混編后的語(yǔ)言叫Objective-C++。有了它晌该,你就能夠在Objective-C利用過(guò)程中利用已有的C++類庫(kù)暑脆。Objective-C和C++混編的關(guān)鍵在 Objective-C++中,能夠用C++代碼調(diào)用措施也能夠從Objective-C調(diào)用措施跛锌。在這兩種語(yǔ)言里對(duì)象都是指針弃秆,能夠在任何地方利用届惋。例如,C++類能夠利用Objective-C對(duì)象的指針作為數(shù)據(jù)成員菠赚,Objective-C類也能夠有C++對(duì)象指針做實(shí)例變量脑豹。下例解釋了這一點(diǎn)。當(dāng)心:Xcode必需源文件以".mm"為伸展名衡查,這么能力啟用編譯器的Objective-C++伸展瘩欺。
#importclass Hello {? private:? id greeting_text; // holds an NSString? public:? Hello() {? greeting_text = @"Hello, world!";? }? Hello(const char* initial_greeting_text) {? greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text];? }? void say_hello() {? printf("%s/n", [greeting_text UTF8String]);? }? };? @inte***ce Greeting : NSObject {? @private? Hello *hello;? }? - (id)init;? - (void)dealloc;? - (void)sayGreeting;? - (void)sayGreeting:(Hello*)greeting;? @end? @implementation Greeting? - (id)init {? if (immolation = [super init]) {? hello = new Hello();? }? return immolation;? }? - (void)dealloc {? delete hello;? [super dealloc];? }? - (void)sayGreeting {? hello->say_hello();? }? - (void)sayGreeting:(Hello*)greeting {? greeting->say_hello();? }? @end? int main() {? NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];? Greeting *greeting = [[Greeting alloc] init];? [greeting sayGreeting]; // > Hello, world!? Hello *hello = new Hello(xj.xjwmz.com"Bonjour, monde!");? [greeting sayGreeting:hello]; // > Bonjour, monde!? delete hello;? [greeting release];? [pool release];? return 0;? } 正如你能夠在OC接口中聲明C構(gòu)造一樣,你也能夠在OC接口中聲明C++類拌牲。跟C構(gòu)造一樣俱饿,OC接口中定義的C++類是大局范圍的,不是OC類的內(nèi)嵌類(這與規(guī)范C(盡管不是C++)晉級(jí)嵌套構(gòu)造定義為文件范圍是統(tǒng)一的)塌忽。為了批準(zhǔn)你基于語(yǔ)言變種條件化地編寫(xiě)代碼拍埠,OC++編譯器定義了__cplusplus和__OBJC__預(yù)處理器常量,離別指定C++和OC土居。如前所述枣购,OC++不批準(zhǔn)C++類繼承自O(shè)C對(duì)象,也不批準(zhǔn)OC類繼承自C++對(duì)象擦耀。class Base { };? @inte***ce ObjCClass: Base ... @end // ERROR!? class Derived: public ObjCClass ... // ERROR! 與 OC不同的是棉圈,C++對(duì)象是靜態(tài)種類的,有運(yùn)行時(shí)多態(tài)是特異情形眷蜓。兩種語(yǔ)言的對(duì)象模型因而不能直接接受分瘾。更大約的,OC和C++對(duì)象在內(nèi)存中的格局是互不相容的吁系,也即便說(shuō)德召,等閑不可能創(chuàng)立一個(gè)對(duì)象實(shí)例從兩種語(yǔ)言的角度來(lái)看都是管用的。因而垮抗,兩種種類層次構(gòu)造不能被混雜氏捞。你能夠在OC類內(nèi)部聲明C++類,編譯器把這些類當(dāng)作已聲明在大局名目空間來(lái)看待冒版。就像下面:@inte***ce Foo {? class Bar { ... } // OK? }? @end? Bar *barPtr; // OK OC批準(zhǔn)C構(gòu)造作為實(shí)例變量液茎,不管它是否聲明在OC聲明內(nèi)部。@inte***ce Foo {? struct CStruct { ... };? struct CStruct bigIvar; // OK? } ... @end Mac OS X 10.4爾后,萬(wàn)一你設(shè)置fobjc- call-cxx-cdtors編譯器符號(hào)捆等,你就能夠利用包括虛函數(shù)和故含義的用戶自定義零參數(shù)構(gòu)造函數(shù)滞造、析構(gòu)函數(shù)的C++類實(shí)例來(lái)做為實(shí)例變量(gcc-4.2默認(rèn)設(shè)置編譯器符號(hào)fobjc-call-cpp-cdtors)。OC成員變量alloc完?duì)柡蠖翱荆琣lloc函數(shù)會(huì)按聲明次序調(diào)用構(gòu)造器谒养。構(gòu)造器利用公共無(wú)參數(shù)穩(wěn)妥的構(gòu)造函數(shù)。OC成員變量dealloc之前明郭,dealloc措施按聲明次序反序調(diào)用調(diào)用析構(gòu)函數(shù)买窟。 OC沒(méi)知名目空間得觀念。不能在C++名目空間內(nèi)部聲明OC類薯定,也不能在OC類里聲明名目空間始绍。OC類,協(xié)議话侄,分類不能聲明在C++ template里亏推,C++ template也不能聲明在OC接口,協(xié)議年堆,分類的范圍內(nèi)吞杭。然而,OC類能夠做C++ template的參數(shù)变丧,C++ template參數(shù)也能夠做OC消息表白式的空氣壓縮機(jī)接收者或參數(shù)(不能穿越selector)芽狗。C++詞匯歧義和抵觸OC頭文件中定義了一些標(biāo)識(shí)符,所有的OC過(guò)程定然包括的锄贷,這些標(biāo)識(shí)符識(shí)id译蒂,Class,SEL谊却,IMP和BOOL柔昼。OC措施內(nèi),編譯器預(yù)聲明了標(biāo)識(shí)符immolation和super炎辨,就想C++中的關(guān)鍵字this捕透。跟C++的this不同的是,immolation和super是上下文相干的碴萧;OC措施外他們還能夠用于等閑標(biāo)識(shí)符乙嘀。協(xié)議內(nèi)措施的參數(shù)列表,有5個(gè)上下文相干的關(guān)鍵字(oneway破喻,in虎谢,out,inout曹质,bycopy)婴噩。這些在其他內(nèi)容中不是關(guān)鍵字擎场。從 OC過(guò)程員的角度來(lái)看,C++添置了不少新的關(guān)鍵字几莽。你依舊能夠利用C++的關(guān)鍵字做OC selector的一局部迅办,因而波及并不嚴(yán)重,但你不能利用他們命名OC類和實(shí)例變量章蚣。例如站欺,盡管class是C++的關(guān)鍵字,然而你依舊能夠利用 NSObject的措施class:[foo class]; // OK 然而纤垂,因?yàn)樗且粋€(gè)關(guān)鍵字矾策,你不能用class做變量名目:NSObject *class; // Error OC里類名和分類名有獨(dú)自的命名空間。@inte***ce foo和@inte***ce(foo)能夠同時(shí)存在在一個(gè)源代碼中洒忧。OC++里蝴韭,你也能用C++中的類名或構(gòu)造名來(lái)命名你的分類。協(xié)議和template標(biāo)識(shí)符利用語(yǔ)法雷同但目標(biāo)不同:idfoo;TemplateTypebar;
為了避免這種籠統(tǒng)之處熙侍,編譯器不批準(zhǔn)把id做template名目。最后履磨,C++有一個(gè)語(yǔ)法歧義蛉抓,當(dāng)一個(gè)label后面跟了一個(gè)表白式表示一個(gè)大局名目時(shí),就像下面:
label: ::global_name = 3;
第一個(gè)冒號(hào)后面必需空格剃诅。OC++有相仿情形巷送,也必需一個(gè)空格:
receiver selector: ::global_c++_name;
局限
OC++ 未曾為OC類添置C++的功能,也未曾為C++類添置OC的功能矛辕。例如笑跛,你不能用OC語(yǔ)法調(diào)用C++對(duì)象,也不能為OC對(duì)象添置構(gòu)造函數(shù)和析構(gòu)函數(shù)聊品,也不能將this和immolation互相輪換利用飞蹂。類的系統(tǒng)構(gòu)造是自力更生的。C++類不能繼承OC類翻屈,OC類也不能繼承C++類陈哑。另外,多語(yǔ)言失常處理是不扶持的伸眶。也就是說(shuō)惊窖,一個(gè)OC拋出的失常不能被C++代碼捉拿,反到來(lái)C++代碼拋出的失常不能被OC代碼捉拿厘贼。尤其是那些能夠輕率在閱讀代碼的時(shí)候覺(jué)察的訛謬界酒,這些訛謬經(jīng)常不輕率穿越機(jī)器上的測(cè)驗(yàn)分辨出來(lái)。