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