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
我在 C++ 中使用类 B 的 void 指针做了类似的事情。但这错过了“类 B 的委托(delegate)应该实现这样那样的方法”的部分。
如何在C++中模仿Objective-C的协议(protocol)?
最佳答案
您的示例的 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.cpp
和 B.cpp
文件(如果需要)。
在此示例中,BDelegate
类是一个抽象基类 (ABC),等同于您的 BDelegate
协议(protocol)。通过仅包含纯虚成员函数(以关键字 virtual
和 =0
后缀开头的函数),它强制其子类为这些方法提供实现,就像使用@required
标签(或无标签)在 Objective-C 协议(protocol)中执行。 BDelegate
仅包含此类函数这一事实使其成为 ABC。
您可以通过在 ABC 中为函数指定一个空主体来模拟 Objective-C @optional
标记,这意味着不需要子类来实现它(因为它在 ABC 中实现).例如,您可以通过如下修改 BDelegate
来模拟可选的 foo
方法:
@protocol BDelegate
- (void) classBsays;
@optional
- (void) foo;
@end
// Is approximately equivalent to:
class BDelegate {
public:
virtual void classBSays( ) = 0;
virtual void foo( ) { }
};
使用该定义,类 A
可以根据需要选择是否为 foo
提供定义。但是请注意,这并不完全等同于 Objective-C 的 @optional
表示法,因为 A
仍将继承 BDelegate
的 foo
方法,如果它不提供它自己的覆盖。另一方面,对于 Objective-C 协议(protocol),A
根本没有这样的方法,除非它自己明确地实现它。
可获得对该主题的更全面介绍 here .
关于c++ - C++ 中的 Objective-C @protocol 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18752500/