嗯,如果我不感到困惑,那么不调用复制构造函数是完全合理的。您是否期望 ivar 被神奇地破坏和复制构造?我想这违反了 C++ 的规则。如果合成的 setter 在概念上是
-(void)setFoo:(Foo)foo_{
foo=foo_;
}
thenoperator=
应该被调用,而不是复制构造函数。
也就是说,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
$
现在,我有上面写的显式设置器,而不是@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 源代码是这个,请参阅GenerateObjCSetter
。在那里,它最终测试是否需要 C++ 赋值运算符。我会说这是一个灰色区域,没有很好的记录,但目前正在实施......