Смешивание С++ и Objective-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);

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

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

Когда я пытаюсь использовать код С++ в Objective-C, я хочу объявить объект С++ как переменную-член в заголовочном файле Objective-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, как в коде на С++? И могу ли я предположить, что деструктор класса Test будет вызываться при уничтожении объекта MyClass?

Или если (2) не подходит в Objective-C ++, то (1) хорошо? Мне нужно вручную вызвать delete m_testObjectPtr в dealloc?

Ответ 1

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

std::vector<CCSprite *> spriteList;

просто убедитесь, что вы сохранили их, когда вы вставляете их в список и отпустите их, когда вы их удаляете.
В обоих случаях вы можете сделать собственный собственный указатель, который вызывает сохранение и освобождение в конструкторе/уничтожении/копировании, как необходимо, а затем не беспокойтесь о сохранении выпуска.
Также деструктор для объектов С++ будет вызываться автоматически, когда объект будет освобожден.
Примером объектной 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);

и не заботятся о сохранении/выпуске

Ответ 2

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

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

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

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

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

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