5

クラス A はクラス B のインスタンスをメンバーとして持っています。クラス B のインスタンスがクラス A と通信したい場合があります。Objective-C では、次のことができます。

// A.h
@interface A : NSObject <BDelegate>
@property (nonatomic, retain) B *b;
@end 

// A.m
- (void) classBsays {

}


// B.h
@protocol BDelegate
- (void) classBsays;
@end

@interface B : NSObject
@property (nonatomic, assign) id<BDelegate> delegate;
@end

// B.m
@implementation B
- (void) f {
    [delegate classBsays];
}
@end

クラス B で void ポインターを使用して、C++ で同様のことを行いました。

C++ で Objective-C のプロトコルを模倣するにはどうすればよいですか?

4

2 に答える 2

5

あなたの例に相当する C++ は次のようになります。

// A.hpp
#include "B.hpp"

class A : public BDelegate {
    public:
        void classBSays ( ) { }
        B* b;
};

// B.hpp
class BDelegate {
    public:
        virtual void classBSays( ) = 0;
};
class B {
    public:
        void f ( ) { delegate->classBSays( ); }
        BDelegate* delegate;
};

簡潔にするために、ここではメンバー関数のインライン実装を使用していることに注意しA.classBSays()てください。B.f()A.cppB.cpp

この例では、クラスはプロトコルBDelegateに相当する抽象基本クラス (ABC)です。BDelegate純粋な仮想メンバー関数 (キーワードvirtualと接尾辞が前に付いた関数) のみを含めることにより、Objective-C プロトコルでタグを使用する (またはタグ=0を使用しない) 場合と同様に、そのサブクラスにそれらのメソッドの実装を提供するように強制します。@requiredそのような機能だけが含まれているという事実がBDelegateABCなのです。

ABC の関数に空の本体を指定することで、Objective-C タグをエミュレートでき@optionalます。これは、サブクラスを実装する必要がないことを意味します (ABC に実装されているため)。たとえば、次fooのように を変更して、オプションのメソッドをエミュレートできます。BDelegate

@protocol BDelegate
- (void) classBsays;
@optional
- (void) foo;
@end
// Is approximately equivalent to:
class BDelegate {
    public:
        virtual void classBSays( ) = 0;
        virtual void foo( ) { }
};

その定義を使用して、クラスは必要に応じAて定義を提供するかどうかを選択できますfoo。ただし、独自のオーバーライドを提供しない場合でものメソッドを継承する@optionalため、これは Objective-C 表記と完全に同等ではないことに注意してください。一方、Objective-C プロトコルでは、それ自体を明示的に実装しない限り、そのようなメソッドはまったくありません。ABDelegatefooA

このテーマのより完全な紹介は、ここで入手できます。

于 2013-09-11T22:58:44.813 に答える