Добавить указатель на определенный класс 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++. Я настоятельно рекомендую вам прочитать статью, чтобы понять все детали этого решения.