混合C ++和Objective-C

时间:2011-11-17 18:12:30

标签: c++ objective-c boost cocos2d-iphone smart-pointers

我使用C ++作为应用程序主干和GUI的Objective-C,这很好。

但是当谈到在Objective-C ++(.mm文件)中将这些代码混合在一起时,我有一些问题:

1。我可以将STL容器与Objective-C或Cocos2D对象混合使用吗?

E.g。在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。使用Objective-C中的C ++智能指针对象进行内存管理?

当我尝试在Objective-C中使用C ++代码时,我想在Objective-C头文件中将C ++对象声明为成员变量。

假设我在test.h标题中声明了一个C ++类:

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)好吗?我可以像在C ++代码中一样在Objective-C中使用智能指针吗?我可以假设在Test对象被销毁时将调用MyClass类析构函数吗?

或者如果(2)在Objective-C ++中不合适,(1)好吗?我需要手动拨打电话吗? delete m_testObjectPtr中的dealloc

2 个答案:

答案 0 :(得分:7)

您只能在c ++类上使用智能指针。如果您在objective-c类上使用then,您将遇到编译错误或在某处崩溃 您还可以使用带有Objective-c类指针的容器,例如

std::vector<CCSprite *> spriteList;

确保在将它们插入列表时保留它们,并在删除它们时将其释放 在这两种情况下,您都可以创建自己的智能指针,在构造函数/销毁/复制中调用retain和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);

并且不关心保留/释放

答案 1 :(得分:4)

您需要注意一些问题。在制作Objective-C ++对象的类成员时,C ++类不会享受与生成相同的基于生存期的生命周期。当alloc / init时,将不会调用构造函数,而当releasing时,将不会调用析构函数,除非您仔细使用new / delete或抓住指针并使用new / delete明确管理它。

此外,如果需要与Objective-C文件共享Objective-C ++标头,则根本不能使用任何C ++结构。通过使用pimpl模式隐藏所有C ++成员可以减轻这两个问题。

我可以将STL容器与Objective-C或Cocos2D对象混合使用吗?

是的,因为Objective-C对象只是指向结构的指针,所以你可以很容易地将它们存储在STL容器中,甚至可以向前声明类型并将其传递给纯C ++代码。 (注意,C ++代码在没有棘手和脆弱代码的情况下对指针的影响不大,但是您可以随后将指针传回Objective-C代码以完成有用的工作。)

使用Objective-C中的C ++智能指针对象进行内存管理?

您可以使用智能指针来管理Objective-C对象的生命周期,但是您需要注意它们不会调用delete(大多数C ++智能指针的默认行为)。使用C ++ 11或boost中的shared_ptr,您可以提供自定义删除器;虽然现在你有两个引用计数系统。您可以使用boost :: intrusive_ptr来跳过额外的开销并直接使用Objective-C的引用计数。