我对 obj-c 非常熟悉,现在我正在尝试更深入地研究 C++。
我正在寻找 obj-c 委托模式的 C++ 等价物。
您只需继承类(协议),而不是遵守协议。一个小例子:
class Delegate
{
public:
// Some pure virtual method here.
virtual void method() = 0;
};
class A : Delegate
{
void method() { // Do something here... };
};
class B
{
Delegate your_delegate;
// Somewhere in your code you might need to call the method() using: your_delegate.method();
};
没有真正的 1:1 等价物。Objective C 是一种有点动态类型的语言。Obj-C 中的Aprotocol
就像一个承诺,具有某些签名的函数(“选择器”)将在运行时存在。如果你不想,你不必实现它们,但如果你不希望事情在运行时崩溃,你应该实现它们,除非它们被标记为@optional
.
相比之下,C++ 是 100% 静态类型的。如果你说某个函数应该存在,那么它必须存在,否则程序将无法编译。如果超类将函数声明为抽象函数,则子类必须继承它。多重继承(如果你想让一个类实现多个解耦协议,你需要它)是一个雷区。
静态类型 (C++) 的优点是您可以在编译时知道您的程序在功能上是否完整(是否每个应该有代码的地方都有代码)。但是,这样做的代价是有时您必须想出其他解决方案来填充 Obj-C 的协议和委托。
“代表”一词仍然适用。没有句法模式,但您可以使用常用工具通过框架对其进行建模。
这里有很多代码,但是界面很干净。用户必须做的只是底部的一小段代码。仍然有一些与构造函数相关的样板,但这将在未来使用 C++11“继承构造函数”语法消失。
/* Class to be used as a member of the delegation host.
Keeps a list of event clients, which you can iterate over.
As a C++11 convenience, function call operator() is overloaded to call
all clients with the given argument list.
This is templated over the base type for the clients. The base type
should define virtual function(s) for handling the events.
Templating is necessary because we can't anticipate the number or types
of these virtual functions. */
template< typename delegate >
struct delegator {
typedef std::list< delegate * > list; // host interface
list delegates;
typedef typename list::iterator delegate_id; // client interface
delegate_id add( delegate *d )
{ return delegates.insert( delegates.end(), d ); }
void remove( delegate_id d )
{ delegates.erase( d ); }
#if __cplusplus >= 201103L // C++11-only convenient host interface
template< typename ... args >
void operator() ( args && ... a ) {
for ( auto d : delegates ) ( *d )( std::forward< args >( a ) ... );
}
#endif
};
/* Abstract base class for all delegate bases. Registers and unregisters
from the delegator, but doesn't define any event handler. */
template< typename derived >
struct delegate {
typedef ::delegator< derived > delegator;
delegator &source;
typename delegator::delegate_id id;
delegate( delegator &in_source )
: source( in_source ),
id( source.add( static_cast< derived * >( this ) ) ) {}
virtual ~delegate() { source.remove( id ); }
};
/* Example delegate base. Defines an event handler which clients must implement.
Other types of events might declare other bases. */
struct my_delegate_base : delegate< my_delegate_base > {
typedef delegate< my_delegate_base > base;
typedef base::delegator delegator;
my_delegate_base( delegator &d ) : base( d ) {}
virtual void operator() ( int ) = 0;
};
/* Example client class defines how to handle an event. */
struct my_delegate_impl : my_delegate_base {
my_delegate_impl( delegator &d ) : my_delegate_base( d ) {}
virtual void operator() ( int i ) {
std::cout << i << '\n';
}
};