我们都知道Objective-C ++是如何记录在案的。我找不到任何相关内容,但我也发现很难找到合适的明确搜索词。 所以,Stackoverflow来救援(我希望)!
我有一个C ++类,我在Objective-C(++)类中有一个实例(我启用了项目设置,可以调用构造函数/析构函数)。
这一切正常,直到我尝试通过@synthesize
d属性公开实例。我将它设为assign
属性(因为Obj-C保留计数不适用)。该属性似乎工作,除非我设置实例,我希望涉及复制构造函数。
我实际看到的是创建了一个临时实例(上的复制构造函数被调用) - 这是所有预期的。但是,ivar实例上的复制构造函数是 not 。这些值是“神奇地”设置的。我假设@synthesize
d代码正在执行类似memcpy
的操作作为最后一步。这适用于C struct
,但对C ++ class
不太有用,其中代码的正确性取决于正确调用的复制构造函数和赋值运算符。
有没有人更深入地研究过这个问题,让它发挥作用,或者确认无法在Obj-C(++)类中将C ++对象保存为ivars并且具有{{1}调用的复制构造函数} d属性设置者?
(如果有必要,我可以发布所有这些的示例代码 - 但即使是最小版本也是一个屏幕左右)。
答案 0 :(得分:5)
-(void)setFoo:(Foo)foo_{
foo=foo_;
}
然后应该调用operator=
,而不是复制构造函数。
那说,operator=
也没有被调用,无赖(10.6.4,gcc 4.2.1。)!这是示例代码:
#import <Foundation/Foundation.h>
class Foo{
int a,b;
public:
Foo():a(0),b(0){NSLog(@"default constructor for %p",this);}
Foo(const Foo&foo):a(foo.a),b(foo.b){NSLog(@"copy constructor for %p",this);}
Foo& operator=(const Foo& foo){
NSLog(@"assignment operator for %p",this);
a=foo.a;
b=foo.b;
return *this;
}
};
@interface Bar:NSObject {
Foo foo;
}
@property (assign) Foo foo;
@end
@implementation Bar
@synthesize foo;
@end
int main(){
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
Bar* bar=[[Bar alloc] init];
Foo foo;
bar.foo=foo;
[pool drain];
}
将其保存到boo.mm
,我有:
$ g++ -fobjc-call-cxx-cdtors boo.mm -framework Foundation
$ ./a.out
2010-09-04 12:32:06.570 a.out[24352:903] default constructor for 0x10010cdc8
2010-09-04 12:32:06.572 a.out[24352:903] default constructor for 0x7fff5fbff7e0
2010-09-04 12:32:06.573 a.out[24352:903] copy constructor for 0x7fff5fbff7d0
$
现在,我有上面写的明确的setter而不是@synthesize Foo
,我正确地
$ ./a.out
2010-09-04 12:42:22.206 a.out[24417:903] default constructor for 0x10010cdc8
2010-09-04 12:42:22.209 a.out[24417:903] default constructor for 0x7fff5fbff7e0
2010-09-04 12:42:22.210 a.out[24417:903] copy constructor for 0x7fff5fbff7d0
2010-09-04 12:42:22.210 a.out[24417:903] assignment operator for 0x10010cdc8
生成合成setter的clang源代码为this,请参阅GenerateObjCSetter
。在那里,它最终测试是否需要C ++赋值运算符。我会说这是一个灰色地带,没有详细记录,但目前正在实施......
答案 1 :(得分:0)
具有属性的一般规则是,如果您需要特定的行为,即生成的默认样板文件无法为您提供,请为您的-setFoo:
属性编写自己的foo
方法,该方法可以满足您的需要。属性的自动合成是针对常见情况的,它们并不适用于所有地方。在这些情况下,请为酒店提供您自己的二传手或吸气剂。