[英]Objective-C @protocol equivalent in C++
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类委托应该实现这样的方法”的部分。
如何在C ++中模仿Objective-C的协议?
您的示例的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.cpp
和B.cpp
文件中同样实现A.classBSays()
和Bf()
。
在此示例中,类BDelegate
是一个抽象基类(ABC),相当于您的BDelegate
协议。 通过仅包含纯虚拟成员函数(前面带有关键字virtual
和后缀为=0
函数),它强制其子类为这些方法提供实现,就像在目标中使用@required
标记(或没有标记)一样。 C协议。 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
不提供它自己的覆盖, A
仍会继承BDelegate
的foo
方法。 另一方面,使用Objective-C协议, A
根本没有这样的方法,除非它本身明确地实现它。
更全面地介绍了该主题,请点击这里 。
通过定义抽象基类,您可以在C ++中实现基本相同。 也就是说,您只定义方法签名而不提供任何实现。 这需要任何子类来实现声明的方法。
以下是您转换为C ++的示例:
// A.h
class A : public BDelegate {
B *b;
};
// A.m
Result A::classBsays {
}
// B.h
class BDelegate {
virtual Result classBsays() = 0;
};
class B {
BDelegate* delegate;
};
// B.m
void B::f {
delegate->classBsays();
}
请注意,这可能无法编译,因为它缺少一些重要的东西。 你需要一个构造函数,传入B引用,甚至可能使用std::shared_ptr
作为委托,依此类推。 但总体形状是这样的。
重要的部分是BDelegate::classBsays()
的方法声明在方法签名之后具有= 0
,并且没有实现主体。 这意味着该方法是纯虚方法,这意味着子类必须实现该方法,否则无法实例化。 (这是有道理的,否则你可能会调用一个没有实现的方法!)任何具有一个或多个纯虚方法的类本身就是一个纯虚拟类。 这正如您所描述的那样非常常用,用于定义将系统的不同部分分离的接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.