5

Objective-C++ がまばらに文書化されていることは誰もが知っています。これについては何も見つかりませんが、適切で明確な検索用語を見つけるのも難しいと感じています. だから、救助へのStackoverflow(私は願っています)!

私は Objective-C(++) クラス内にインスタンスを持つ C++ クラスを持っています (そして、コンストラクター/デストラクタが呼び出されるようにプロジェクト設定を有効にしています)。

@synthesized プロパティを介してインスタンスを公開しようとするまで、これはすべて正常に機能します。私はそれをassignプロパティにします (Obj-C 保持カウントは適用されないため)。コピーコンストラクターが関与すると予想されるインスタンスを設定する場合を除いて、プロパティは機能しているように見えます。私が実際に見ているのは、一時的なインスタンスが作成されていることです(そのコピーコンストラクターが呼び出されいます)-これはすべて予想されています。ただし、ivar インスタンスのコピー コンストラクターは呼び出されません。値は「魔法のように」設定されます。@synthesized コードはmemcpy最終ステップとしてa のようなことをしていると思います。これはstructC では問題ありませんが、C++ ではあまり役に立ちません。classコードの正確性は、適切に呼び出されるコピー コンストラクターと代入演算子に依存します。

誰かがこれをさらに詳しく調べたり、動作させたり、C++ オブジェクトを Obj-C(++) クラスの ivar として保持したり、@synthesized プロパティ セッターによって呼び出されたコピー コンストラクターを持ったりすることができないことを確認しましたか?

(必要に応じて、これらすべてのサンプル コードを投稿できますが、最小バージョンでも画面一杯程度です)。

4

2 に答える 2

5

うーん、私が混乱していなければ、コピー コンストラクターが呼び出されないのは完全に合理的です。ivar が魔法のように破壊され、コピー構築されると思いますか? それはC++のルールに反していると思います。合成されたセッターが概念的に

-(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
$

さて、 の代わりに上で書いた明示的なセッターがありましたが@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

合成されたセッターを生成するためのclangソースコードはこれです。を参照してくださいGenerateObjCSetter。そこで、最終的に C++ 代入演算子が必要かどうかをテストします。十分に文書化されていませんが、現在実装されている灰色の領域だと思います...

于 2010-09-04T16:46:46.110 に答える
0

プロパティの一般的なルールは、生成されたデフォルトのボイラープレートでは提供できない特定の動作が必要な場合は、必要なことを行う独自のプロパティの-setFoo:メソッドを作成することです。fooプロパティの自動合成は一般的なケースを想定しており、どこにでも適用できるわけではありません。そのような場合は、プロパティに独自のセッターまたはゲッターを提供します。

于 2010-09-04T16:06:14.843 に答える