使用C、C++、Objective-C三語言混編時的注意事項

 C++和C混編: 
    1. auto關鍵字在C++11後改變了含義,如果C代碼中有出現auto關鍵字,拷貝到.cpp中一定要將所有的auto刪除  
       
      int a = 8;
      register int b = 9;
      auto int c = 10; // 在.cpp中應該刪除這裏的auto
      static int d = 11;



    2. const關鍵字,如果在C語言中被用來聲明一個外部const量,拷貝到.cpp中需要添加extern關鍵字
       
      const int a; // C語言中用作聲明一個外部const量a在.cpp文件中會報錯
      const int b = 9; // 定義一個const量
      extern const int c; // 聲明一個外部const量c





       

    3. 如果需要在.c文件中調用.cpp文件中的函數,必須在定義該函數是添加extern "C"
       
      // .cpp
      extern "C" void func1() { // 此函數將以C語言形式編譯
      }
      void func1(int a) { // 在cpp中仍可將函數重載,但是不可將重載函數也聲明成C函數
      }
      // .c
      void func1(); // 正常聲明
      void func2() {
          func1(); // 可以調用.cpp中的函數
      }













       

    4.  在.cpp文件中調用C語言頭文件時,如果按照原始方式(.h)來調用,則會與在C語言中使用完全相同,如果採用兼容形式(c*),部分函數將會有重載或重寫
       

      // 原始方式
      #include <math.h>
      void func1() {
          int a = abs(4); // 必須傳整型
          double b = fabs(3.5); // 必須傳浮點型
      }
      // 兼容方式
      #include <cmath> // 包含了STL對<typename T>std::abs(T num)的定義
      void func2() {
          int a = std::abs(4); // 可以傳整型
          double b = std::abs(7.5); // 也可以傳浮點型
      }














       
 Objective-C和C++混編(基本原則就是把.m文件當成.c文件來看待,道理同上)
    1. 在一個.mm文件中可以同時出現Objective-C代碼和C++代碼,兩者語法互不影響,但是繼承不可混用
       
      #import <Foundation/Foundation.h>
      #import <iostream> // 可以使用import來包含STL庫頭文件,但是此時不能自動處理重複包含,效果與include完全相同
      class CppClass; // C++類按照C++類的聲明來書寫,所以這裏不能寫作@class,如果是聲明OC類則需要寫@class
      @interface OCClass : NSObject /*不能讓OCClass繼承自std::string等C++類*/ {
          CppClass *_cp; // 成員中可以定義指向C++對象的指針,但不能直接定義C++對象,並且該指針不能通過@property來自動生成getter和setter,需要手動書寫
      }
      @property int men1;
      - (void)show;
      @end
      class CppClass {
      public:
          int men;
          OCClass *op; // 這裏也可以定義指向OC對象的指針
          CppClass(int men):men(men) { // 指向OC對象的指針無法寫入初始化列表,因此不能將該指針聲明爲const成員
              op = [[OCClass alloc] init]; // 只能在函數體中來初始化
          }
          friend std::ostream &operator <<(std::ostream &stream, CppClass &temp) {
              NSLog(@"%d\t%@", temp.men, temp.op); // 可以調用Cocoa框架中的方法,但傳參時只能傳OC對象以及C語言的數據類型,不可以將C++對象(例如std::string)傳入OC函數
              return stream;
          }
      };
      @implementation OCClass
      - (NSString *)description {
          return [NSString stringWithFormat:@"%d", self.men1];
      }
      - (instancetype)init {
          if (self = [super init]) {
              _cp = new CppClass(1); // 由於不能定義成員對象,只能定義指針,因此需要在初始化方法中使用new來創建C++對象
          }
          return self;
      }
      @end








































    2. 如果在.mm中書寫普通函數,則默認爲C++函數,不能夠在.m文件中直接調用,否則需要加上extern "C"。
    3. 如果需要.m文件和.cpp 文件對接,有兩種方法: 
        1. 書寫C語言函數(注意在.cpp中需要按照C方式定義,加上extern "C"關鍵字)作爲接口,進行C語言類型數據的傳遞; 
        2. 書寫一個.mm文件作爲接口,將C++對象包裝到OC類中使得.m文件可以調用,將OC對象包裝到C++類中使得.cpp文件可以調用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章