Добавить указатель на определенный класс Objective-C в.h файле Objective-C++

Возможно создать класс в Objective-C++, который имеет поле, которое является указателем на интерфейс Objective-C (внутри .h файл)?

Чтобы немного уточнить, я создал один интерфейс Objective C:

// Our platform independent class
@interface LoggerDelegate : NSObject<SomeDelegate>
@end

Я могу создать это внутри .mm файл, и он работает, но он предназначен для глобальной переменной, и мне не разрешено изменять его область. Так что я хотел бы использовать его внутри Logger.h:

class Logger {
public:

private:

LoggerDelegate* _ptr;   //<--- pointer to the Objective-C interface
};

Когда я определяю свой интерфейс внутри Logger.mm оно работает. Но возможно ли объединить код Objective-C++ из Objective-C и C++ внутри .h файлы? Или это возможно только в .mm файлы?

1 ответ

Языковая семья

Objective-C использует .h заголовки и .m файлы реализации. Вам может не понадобиться последний в случае абстрактного интерфейса. Все эти файлы должны соответствовать синтаксису Objective C:

  • Вы можете использовать некоторый синтаксис C в .h или же .m; это будет признано, потому что Цель C является расширением языка C.
  • чистые элементы языка C++ (например, class или же template) не будет распознаваться компилятором Objective-C.

Objective-C++ использует также .h заголовки но .mm файлы реализации. Оба должны соответствовать синтаксису Objective-C++:

  • Большая часть синтаксиса C++ будет распознана, потому что Objective C++ основан на C++.
  • Весь синтаксис Objective C будет распознан, потому что Objective C является подмножеством Objective C++.

Стандартный C++ использует заголовки (обычно .h или же .hpp) и файлы реализации (обычно .cc или же .cpp). Они должны использовать только элементы языка C++. Элементы языка Objective-C и Objective-C++, которые не принадлежат C++, такие как, например, @interface вызовет ошибки компиляции C++.

Смешивание языков - проблемы с синтаксисом

Смешивание Objective-C и Objective-C++: если вы разделяете заголовки (.h) между Objective-C и Objective C++ они должны будут соответствовать как Objective-C, так и Objective-C++. Следовательно, заголовок может использовать только общий знаменатель между двумя языками, то есть языковые элементы Objective-C (и C).

Смешивание стандартного C++ и объективного C/C++. Вы можете комбинировать язык C++ с конструкциями Objective-C или Objective-C++ только в Objective-C++ (так .mm файлы, и в конце концов .h если и только если не включен ни в один стандартный исходный код C++ или Objective-C)

Вот почему вы можете использовать свой интерфейс Objective C в .mm файл. Но вы не можете использовать его в .h файл, который будет включен в код C++.

Смешивание языков - семантические проблемы

Объектная модель и жизненный цикл стандарта C++ и Objective-C/C++ не совпадают. Это затрудняет взаимодействие. Например, класс C++ не может наследоваться от класса Objective-C, а если класс Objective-C содержит объект C++, конструкция может быть сложной. И не существует языковой конструкции C++, которая гарантированно была бы изначально совместима с Objective-C++ @interface или.

Но разве нет способа взаимодействия с указателями?

Можно управлять указателями от объектов C++ до объектов Objective-C++ с помощью идиомы PIMPL (также называемой "непрозрачный указатель"). Эта блестящая статья Фила Джордана объясняет, как это сделать, на примере, который вы можете легко использовать повторно.

Основная идея Фила Джордана - использовать заголовок, чтобы обернуть объект Objective-C++ в стандартный класс C++, используя указатель на неполный объект. Фил использует условную компиляцию умным способом, чтобы позволить использование того же самого .h для межъязыковых целей:

#ifdef __OBJC__
@class XXXX;       // if header used in Objective C++
#else
struct XXXX;        // if header used in standard C++
#endif

class WrapperClass {   // standard C++ class also recognuzed by Objective C++
    XXXX *wrapped_objective_c_object_pointer; 
public:  
    ...// public interface for C++
};

Это гарантирует, что код C++, включающий заголовок, никогда не сможет использовать указатель для выполнения каких-либо операций с обернутым объектом. Реализация класса оболочки C++ будет предоставлена ​​в виде .mm файл, который осведомлен о семантике Objective C++. Я настоятельно рекомендую вам прочитать статью, чтобы понять все детали этого решения.

Другие вопросы по тегам