3

编译 Objective-C++,我得到以下诊断:

'MyClass' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible

缺少复制构造函数和析构函数也会出现类似的错误。添加必要的方法很容易,但它们通常没有意义,特别是对于我想要使其不可复制的类,并且我不会混合 ARC 和非 ARC 代码(至少不是故意的)。

为什么我会收到此消息,我可以在不为所有 C++ 类编写无意义的成员函数的情况下摆脱它吗?

4

2 回答 2

3

这是因为 ARC 不鼓励在POD结构和 C++ 类中使用 Objective-C 对象,因为它们的包含使得管理它们的内存变得模棱两可。您可以通过在 Objective-C 成员前面加上__unsafe_unretained限定符来解决它,这告诉 ARC 保持它的粘性手指离开类,但使您处于不得不自己管理成员对象的内存的尴尬境地。此外,具有内部链接的对象不在警告范围内,因此将您的类或结构包装在不合格的namespace { }作品中也是如此。如果您绝对必须在碰巧将 Objective-C 对象作为类成员的文件(或多个文件)中使用 ARC,则必须提供正确的访问运算符(如警告所述),否则只需关闭 ARC 并省去麻烦。

于 2013-05-22T20:35:52.557 回答
1

The restriction is mentioned in in this section of the ARC specification:

However, nontrivally ownership-qualified types are considered non-POD: in C++11 terms, they are not trivially default constructible, copy constructible, move constructible, copy assignable, move assignable, or destructible. It is a violation of C++’s One Definition Rule to use a class outside of ARC that, under ARC, would have a nontrivially ownership-qualified member.

The reason for it is this: In ARC, when you use an Objective-C object as a field of a C++ struct or class, ARC implicitly adds code to the default constructor, copy constructor, destructor, etc. to manage the memory for the fields. And if the struct or class doesn't have these constructors/destructors, ARC automatically adds them.

This means that if such a struct or class was considered "POD" (a C++ term meaning it has no special constructors/destructors) originally, ARC makes it non-POD by implicitly adding these special constructors/destructors. However, C++ treats POD and non-POD types differently in some places. If such an originally POD struct or class declaration was seen from both non-ARC and ARC code, then the non-ARC code might think that it is still a POD type. But this is wrong (ARC added methods to make it non-POD), and will allow the non-ARC code to do wrong things and bypass the memory management. As a result, it must be disallowed.

于 2013-05-22T22:59:43.037 回答