5

我们都知道 Objective-C++ 的文档很少。我在这方面找不到任何东西,但我也发现很难找到合适的明确搜索词。所以,Stackoverflow 来拯救(我希望)!

我有一个 C++ 类,我在 Objective-C(++) 类中有一个实例(并且我为要调用的构造函数/析构函数启用了项目设置)。

在我尝试通过@synthesized 属性公开实例之前,这一切都很好。我将其assign设为属性(因为 Obj-C 保留计数不适用)。该属性似乎可以工作,除非我设置实例时我希望复制构造函数参与其中。我实际看到的是创建了一个临时实例(调用了其上的复制构造函数 - 这是所有预期的。但是没有调用ivar 实例上的复制构造函数。这些值是“神奇地”设置的。我假设@synthesized 代码正在做类似于 amemcpy作为最后一步的事情。这对 C 来说很好struct,但对 C++ 没有太大帮助classes 其中代码的正确性取决于正确调用的复制构造函数和赋值运算符。

有没有人更深入地研究过这个,让它工作,或者确认不可能将 C++ 对象作为 ivars 保存在 Obj-C(++) 类中并且有由@synthesized 属性设置器调用的复制构造函数?

(如有必要,我可以发布所有这些的示例代码 - 但即使是最小版本也是一个屏幕左右)。

4

2 回答 2

5

嗯,如果我不感到困惑,那么不调用复制构造函数是完全合理的。您是否期望 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++ 赋值运算符。我会说这是一个灰色区域,没有很好的记录,但目前正在实施......

于 2010-09-04T16:46:46.110 回答
0

属性的一般规则是,如果您需要生成的默认样板无法为您提供的特定行为,请-setFoo:为您的属性编写您自己的方法来满足您的foo需要。属性的自动合成适用于常见情况,它们并不适用于任何地方。在这些情况下,请为该属性提供您自己的 setter 或 getter。

于 2010-09-04T16:06:14.843 回答