zoukankan      html  css  js  c++  java
  • C++和ObjectiveC混编(官方文档翻译)

    C++和Objective-C混编(官方文档翻译)
    2011-01-09 12:31

    Using C++ With Objective-C
        苹果的Objective-C编译器允许用户在同一个源文件里自由地混合使用C++和Objective-C,混编后的语言叫Objective-C++。有了它,你就可以在Objective-C应用程序中使用已有的C++类库。

    Objective-C和C++混编的要点
       在Objective-C++中,可以用C++代码调用方法也可以从Objective-C调用方法。在这两种语言里对象都是指针,可以在任何地方使用。例如,C++类可以使用Objective-C对象的指针作为数据成员,Objective-C类也可以有C++对象指针做实例变量。下例说明了这一点。
        注意:Xcode需要源文件以".mm"为扩展名,这样才能启动编译器的Objective-C++扩展。

     
    复制代码
    1. /* Hello.mm
    2.  * Compile with: g++ -x objective-c++ -framework Foundation Hello.mm  -o hello
    3.  */
    4. #import <Foundation/Foundation.h>
    5. class Hello {
    6. private:
    7.     id greeting_text;  // holds an NSString
    8. public:
    9.     Hello() {
    10.         greeting_text = @"Hello, world!";
    11.     }
    12.     Hello(const char* initial_greeting_text) {
    13.         greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text];
    14.     }
    15.     void say_hello() {
    16.         printf("%s\n", [greeting_text UTF8String]);
    17.     }
    18. };
    19. @interface Greeting : NSObject {
    20. @private
    21.     Hello *hello;
    22. }
    23. - (id)init;
    24. - (void)dealloc;
    25. - (void)sayGreeting;
    26. - (void)sayGreeting:(Hello*)greeting;
    27. @end
    28. @implementation Greeting
    29. - (id)init {
    30.     if (self = [super init]) {
    31.         hello = new Hello();
    32.     }
    33.     return self;
    34. }
    35. - (void)dealloc {
    36.     delete hello;
    37.     [super dealloc];
    38. }
    39. - (void)sayGreeting {
    40.     hello->say_hello();
    41. }
    42. - (void)sayGreeting:(Hello*)greeting {
    43.     greeting->say_hello();
    44. }
    45. @end
    46. int main() {
    47.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    48.    
    49.     Greeting *greeting = [[Greeting alloc] init];
    50.     [greeting sayGreeting];                         // > Hello,  world!
    51.    
    52.     Hello *hello = new Hello("Bonjour, monde!");
    53.     [greeting sayGreeting:hello];                   // > Bonjour,  monde!
    54.    
    55.     delete hello;
    56.     [greeting release];
    57.     [pool release];
    58.     return 0;
    59. }


        正如你可以在OC接口中声明C结构一样,你也可以在OC接口中声明C++类。跟C结构一样,OC接口中定义的C++类是全局范围的,不是OC类的内嵌类(这与标准C(尽管不是C++)提升嵌套结构定义为文件范围是一致的)。
        为了允许你基于语言变种条件化地编写代码,OC++编译器定义了__cplusplus和__OBJC__预处理器常量,分别指定C++和OC。    如前所述,OC++不允许C++类继承自OC对象,也不允许OC类继承自C++对象。

     
    复制代码
    1. class Base { /* ... */ };
    2. @interface ObjCClass: Base ... @end // ERROR!
    3. class Derived: public ObjCClass ... // ERROR!


       与OC不同的是,C++对象是静态类型的,有运行时多态是特殊情况。两种语言的对象模型因此不能直接兼容。更根本的,OC和C++对象在内存中的布局是互不相容的,也就是说,一般不可能创建一个对象实例从两种语言的角度来看都是有效的。因此,两种类型层次结构不能被混合。
        你可以在OC类内部声明C++类,编译器把这些类当作已声明在全局名称空间来对待。就像下面: 

     
    复制代码
    1. @interface Foo {
    2.     class Bar { ... } // OK
    3. }
    4. @end
    5. Bar *barPtr; // OK


        OC允许C结构作为实例变量,不管它是否声明在OC声明内部。

     
    复制代码
    1. @interface Foo {
    2.    struct CStruct { ... };
    3.    struct CStruct bigIvar; // OK
    4. } ... @end


        Mac OS X 10.4以后,如果你设置fobjc-call-cxx-cdtors编译器标志,你就可以使用包含虚函数和有意义的用户自定义零参数构造函数、析构函数的C++类实例来做为实例变量(gcc-4.2默认设置编译器标志fobjc-call-cpp-cdtors)。OC成员变量alloc完以后,alloc函数会按声明顺序调用构造器。构造器使用公共无参数恰当的构造函数。OC成员变量dealloc之前,dealloc方法按声明顺序反序调用调用析构函数。    OC没有名称空间得概念。不能在C++名称空间内部声明OC类,也不能在OC类里声明名称空间。
        OC类,协议,分类不能声明在C++ template里,C++ template也不能声明在OC接口,协议,分类的范围内。
        但是,OC类可以做C++ template的参数,C++ template参数也可以做OC消息表达式的接收者或参数(不能通过selector)。

    C++词汇歧义和冲突
        OC头文件中定义了一些标识符,所有的OC程序必须包含的,这些标识符识id,Class,SEL,IMP和BOOL。
        OC方法内,编译器预声明了标识符self和super,就想C++中的关键字this。跟C++的this不同的是,self和super是上下文相关的;OC方法外他们还可以用于普通标识符。
        协议内方法的参数列表,有5个上下文相关的关键字(oneway,in,out,inout,bycopy)。这些在其他内容中不是关键字。
       从OC程序员的角度来看,C++增加了不少新的关键字。你仍然可以使用C++的关键字做OC selector的一部分,所以影响并不严重,但你不能使用他们命名OC类和实例变量。例如,尽管class是C++的关键字,但是你仍然能够使用NSObject的方法class:

     
    复制代码
    1. [foo class]; // OK


        然而,因为它是一个关键字,你不能用class做变量名称:

     
    复制代码
    1. NSObject *class; // Error


        OC里类名和分类名有单独的命名空间。@interface foo和@interface(foo)能够同时存在在一个源代码中。OC++里,你也能用C++中的类名或结构名来命名你的分类。
        协议和template标识符使用语法相同但目的不同:

     
    复制代码
    1. id<someProtocolName> foo;
    2. TemplateType<SomeTypeName> bar;


        为了避免这种含糊之处,编译器不允许把id做template名称。    最后,C++有一个语法歧义,当一个label后面跟了一个表达式表示一个全局名称时,就像下面:

     
    复制代码
    1. label: ::global_name = 3;


        第一个冒号后面需要空格。OC++有类似情况,也需要一个空格:

     
    复制代码
    1. receiver selector: ::global_c++_name;
  • 相关阅读:
    Account group in ERP and its mapping relationship with CRM partner group
    错误消息Number not in interval XXX when downloading
    错误消息Form of address 0001 not designated for organization
    Algorithm类介绍(core)
    梯度下降与随机梯度下降
    反思
    绘图: matplotlib核心剖析
    ORB
    SIFT
    Harris角点
  • 原文地址:https://www.cnblogs.com/ouyangfang/p/2342378.html
Copyright © 2011-2022 走看看