Смешивание C ++ и Objective-C - PullRequest
       43

Смешивание C ++ и Objective-C

11 голосов
/ 17 ноября 2011

Я использую C ++ в качестве основы приложения и Objective-C для графического интерфейса, это нормально.

Но когда дело доходит до смешивания этого кода вместе в Objective-C ++ (файл .mm), я получилнесколько вопросов:

1.Могу ли я смешивать контейнеры STL с объектами Objective-C или Cocos2D?

Например, можно ли в заголовке Objective-C сделать следующее?

#include <vector>
#include <boost\shared_ptr.hpp>
@interface MyClass : NSObject {
  std::vector<boost::shared_ptr<CCSprite> > m_spriteList;
}

И затем в файле .mm,Я хочу сделать

CCSprite* newSprite = [/* cocos2d stuff here... */];
m_spriteList.push_back(newSprite);

Действителен ли приведенный выше код?Это, конечно, в C ++, но я не уверен, когда смешиваю C ++ и Objective-C и Cocos2D.

2.Управление памятью с использованием объекта смарт-указателя C ++ в Objective-C?

Когда я пытаюсь использовать код C ++ в Objective-C, я хочу объявить объект C ++ как переменную-член в заголовочном файле Objective-C.

Скажем, у меня есть класс C ++, объявленный в заголовке test.h:

Test{
};

В файле заголовка Objective-C я хочу сделать

#include "test.h"
#incude <boost/scoped_ptr.hpp>

#include <vector>
@interface MyClass : NSObject {
   Test* m_testObjectPtr; // (1)
   boost::scoped_ptr<Test>  m_testOjbSmartPtr; // (2)
}

Вприведенный выше код, это (2) хорошо?Могу ли я использовать умные указатели в Objective-C так же, как в коде C ++?И можно ли предположить, что деструктор класса Test будет вызван, когда объект MyClass будет уничтожен?

Или, если (2) не в порядке в Objective-C ++, в порядке (1)?Нужно ли мне вручную звонить delete m_testObjectPtr в dealloc?

Ответы [ 2 ]

7 голосов
/ 17 ноября 2011

Вы можете использовать умный указатель только на классах c ++. если вы используете затем в классах target-c, вы либо получите ошибку компиляции, либо где-нибудь произойдет сбой.
Вы также можете использовать контейнеры с указателями классов target-c, таких как

std::vector<CCSprite *> spriteList;

просто убедитесь, что вы сохранили их, когда вставляете их в список, и отпускаете их, когда удаляете их.
В обоих случаях вы можете создать собственный умный указатель, который вызывает retain и release в constructor / destruct / copy по мере необходимости, а затем не беспокоиться о сохранении release.
Также деструктор для объектов-членов c ++ будет вызываться автоматически при освобождении объекта.
Примером обёртки объекта c будет

template<typename T>
struct shared_objc_object
{
    T *Object;
    shared_objc_object : Object(nil) { }
    shared_objc_object(T *Object) : Object([Object retain]) { }
    shared_objc_object(shared_objc_object &other) :
        Object([other.Object retain]) { }
    ~shared_objc_object() { [Object release]; }
    shared_objc_object &operator =(shared_objc_object &other)
    {
        [Object release];
        Object = [other.Object retain];
    }
}

И вы можете использовать

std::vector<shared_objc_object<CCSprite *>> spriteList;
spriteList.push_back(some_sprite);

и не заботится о сохранении / освобождении

4 голосов
/ 18 ноября 2011

Есть некоторые проблемы, о которых вы хотите знать.Классы C ++ не обладают тем же временем жизни, основанным на области видимости, которое вы могли бы использовать, когда они превращаются в члены класса объектов Objective-C ++.Когда alloc / init ing, конструктор не будет вызван, а когда releasing, деструктор не будет вызван, если вы не используете осторожно на месте new / delete или не держитесь зауказатель и явное управление им с помощью new / delete.

Кроме того, если заголовок Objective-C ++ необходимо использовать совместно с файлами Objective-C, вы вообще не можете использовать какие-либо конструкции C ++.Обе проблемы можно решить, скрыв все члены C ++ с помощью шаблона pimpl.

Можно ли смешивать контейнеры STL с объектами Objective-C или Cocos2D?

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

Управление памятью с использованием объекта смарт-указателя C ++ в Objective-C?

Вы можете использовать интеллектуальные указатели для управления временем жизни ваших объектов Objective-C, но вам нужно быть осторожным, чтобы они не вызывалиdelete (поведение по умолчанию для большинства интеллектуальных указателей C ++).С shared_ptr из C ++ 11 или boost вы можете предоставить пользовательское удаление;хотя теперь у вас есть две системы подсчета ссылок.Вместо этого вы можете использовать boost :: intrusive_ptr, чтобы пропустить эти дополнительные издержки и напрямую использовать подсчет ссылок Objective-C.

...