iphone开发之C++和Objective-C混编
C++和Objective-C混編(官方文檔翻譯)
原文網(wǎng)址:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html
?
Using C++ With Objective-C
??? 蘋果的Objective-C編譯器允許用戶在同一個源文件里自由地混合使用C++和Objective-C,混編后的語言叫Objective-C++。有了它,你就可以在Objective-C應(yīng)用程序中使用已有的C++類庫。
?
Objective-C和C++混編的要點
?? 在 Objective-C++中,可以用C++代碼調(diào)用方法也可以從Objective-C調(diào)用方法。在這兩種語言里對象都是指針,可以在任何地方使用。例 如,C++類可以使用Objective-C對象的指針作為數(shù)據(jù)成員,Objective-C類也可以有C++對象指針做實例變量。下例說明了這一點。
??? 注意:Xcode需要源文件以".mm"為擴展名,這樣才能啟動編譯器的Objective-C++擴展。
/* Hello.mm
? * Compile with: g++ -x objective-c++ -framework Foundation Hello.mm? -o hello
? */
?
? #import <Foundation/Foundation.h>
? class 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]);
? ??? }
? };
?
? @interface Greeting : NSObject {
? @private
??? Hello *hello;
}
- (id)init;
- (void)dealloc;
? - (void)sayGreeting;
? - (void)sayGreeting:(Hello*)greeting;
@end
@implementation Greeting
- (id)init {
if (self = [super init]) {
?? hello = new Hello();
}
return self;
}
- (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("Bonjour, monde!");
? [greeting sayGreeting:hello];?????????????????? // > Bonjour,? monde!
?
delete hello;
[greeting release];
[pool release];
return 0;
}
?
??? 正如你可以在OC接口中聲明C結(jié)構(gòu)一樣,你也可以在OC接口中聲明C++類。跟C結(jié)構(gòu)一樣,OC接口中定義的C++類是全局范圍的,不是OC類的內(nèi)嵌類(這與標(biāo)準(zhǔn)C(盡管不是C++)提升嵌套結(jié)構(gòu)定義為文件范圍是一致的)。
??? 為了允許你基于語言變種條件化地編寫代碼,OC++編譯器定義了__cplusplus和__OBJC__預(yù)處理器常量,分別指定C++和OC。??? 如前所述,OC++不允許C++類繼承自OC對象,也不允許OC類繼承自C++對象。
?
class Base { /* ... */ };
@interface ObjCClass: Base ... @end // ERROR!
class Derived: public ObjCClass ... // ERROR!
?
?? 與 OC不同的是,C++對象是靜態(tài)類型的,有運行時多態(tài)是特殊情況。兩種語言的對象模型因此不能直接兼容。更根本的,OC和C++對象在內(nèi)存中的布局是互不 相容的,也就是說,一般不可能創(chuàng)建一個對象實例從兩種語言的角度來看都是有效的。因此,兩種類型層次結(jié)構(gòu)不能被混合。
??? 你可以在OC類內(nèi)部聲明C++類,編譯器把這些類當(dāng)作已聲明在全局名稱空間來對待。就像下面:?
?
@interface Foo {
class Bar { ... } // OK
}
@end
Bar *barPtr; // OK
?
??? OC允許C結(jié)構(gòu)作為實例變量,不管它是否聲明在OC聲明內(nèi)部。
?
@interface Foo {
struct CStruct { ... };
struct CStruct bigIvar; // OK
} ... @end
?
??? Mac OS X 10.4以后,如果你設(shè)置fobjc- call-cxx-cdtors編譯器標(biāo)志,你就可以使用包含虛函數(shù)和有意義的用戶自定義零參數(shù)構(gòu)造函數(shù)、析構(gòu)函數(shù)的C++類實例來做為實例變量 (gcc-4.2默認(rèn)設(shè)置編譯器標(biāo)志fobjc-call-cpp-cdtors)。OC成員變量alloc完以后,alloc函數(shù)會按聲明順序調(diào)用構(gòu)造 器。構(gòu)造器使用公共無參數(shù)恰當(dāng)?shù)臉?gòu)造函數(shù)。OC成員變量dealloc之前,dealloc方法按聲明順序反序調(diào)用調(diào)用析構(gòu)函數(shù)。??? OC沒有名稱空間得概念。不能在C++名稱空間內(nèi)部聲明OC類,也不能在OC類里聲明名稱空間。
??? OC類,協(xié)議,分類不能聲明在C++ template里,C++ template也不能聲明在OC接口,協(xié)議,分類的范圍內(nèi)。
??? 但是,OC類可以做C++ template的參數(shù),C++ template參數(shù)也可以做OC消息表達(dá)式的接收者或參數(shù)(不能通過selector)。
?
C++詞匯歧義和沖突
??? OC頭文件中定義了一些標(biāo)識符,所有的OC程序必須包含的,這些標(biāo)識符識id,Class,SEL,IMP和BOOL。
??? OC方法內(nèi),編譯器預(yù)聲明了標(biāo)識符self和super,就想C++中的關(guān)鍵字this。跟C++的this不同的是,self和super是上下文相關(guān)的;OC方法外他們還可以用于普通標(biāo)識符。
??? 協(xié)議內(nèi)方法的參數(shù)列表,有5個上下文相關(guān)的關(guān)鍵字(oneway,in,out,inout,bycopy)。這些在其他內(nèi)容中不是關(guān)鍵字。
?? 從 OC程序員的角度來看,C++增加了不少新的關(guān)鍵字。你仍然可以使用C++的關(guān)鍵字做OC selector的一部分,所以影響并不嚴(yán)重,但你不能使用他們命名OC類和實例變量。例如,盡管class是C++的關(guān)鍵字,但是你仍然能夠使用 NSObject的方法class:
?
?[foo class]; // OK
?
??? 然而,因為它是一個關(guān)鍵字,你不能用class做變量名稱:
?
NSObject *class; // Error
OC里類名和分類名有單獨的命名空間。@interface foo和@interface(foo)能夠同時存在在一個源代碼中。OC++里,你也能用C++中的類名或結(jié)構(gòu)名來命名你的分類。
協(xié)議和template標(biāo)識符使用語法相同但目的不同:
id<someProtocolName> foo;TemplateType<SomeTypeName> bar;
為了避免這種含糊之處,編譯器不允許把id做template名稱。??? 最后,C++有一個語法歧義,當(dāng)一個label后面跟了一個表達(dá)式表示一個全局名稱時,就像下面:
label: ::global_name = 3;
第一個冒號后面需要空格。OC++有類似情況,也需要一個空格:
receiver selector: ::global_c++_name;
?
?
限制
?? OC++ 沒有為OC類增加C++的功能,也沒有為C++類增加OC的功能。例如,你不能用OC語法調(diào)用C++對象,也不能為OC對象增加構(gòu)造函數(shù)和析構(gòu)函數(shù),也不 能將this和self互相替換使用。類的體系結(jié)構(gòu)是獨立的。C++類不能繼承OC類,OC類也不能繼承C++類。另外,多語言異常處理是不支持的。也就 是說,一個OC拋出的異常不能被C++代碼捕獲,反過來C++代碼拋出的異常不能被OC代碼捕獲。
轉(zhuǎn)載于:https://blog.51cto.com/arthurchen/577941
總結(jié)
以上是生活随笔為你收集整理的iphone开发之C++和Objective-C混编的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网上威客的猫腻
- 下一篇: 在一个禁止离婚的国家结婚