Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C @protocol equivalent in C++

Class A has an instance of class B as a member. Sometimes the instance of class B wants to talk to class A. In Objective-C I can do:

// 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

I've done something similar in C++ using a void pointer on class B. But this misses the part that says "class B's delegate should implement such and such methods".

How can I imitate Objective-C's protocol in C++?

like image 358
SundayMonday Avatar asked Sep 11 '13 22:09

SundayMonday


People also ask

What is @protocol in Objective-C?

Any class that declares itself to conform to this protocol must implement the methods and properties dictated in the protocol. Declaring a protocol. Objective-C. In Objective-C, protocols are declared with the “@protocol” keyword. Below is an example of declaring a protocol containing one required method.

How do you delegate in Objective-C?

An Objective-C delegate is an object that has been assigned to the delegate property another object. To create one, you define a class that implements the delegate methods you're interested in, and mark that class as implementing the delegate protocol.

What is ID in Obj C?

“id” is a data type of object identifiers in Objective-C, which can be use for an object of any type no matter what class does it have. “id” is the final supertype of all objects.

How do you make an optional protocol in Objective-C?

Optional Protocol methods can be marked as optional using the @optional keyword. Corresponding to the @optional modal keyword, there is a @required keyword to formally denote the semantics of the default behavior. You can use @optional and @required to partition your protocol into sections as you see fit.


1 Answers

The C++ equivalent of your example looks something like this:

// 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;
};

Note that I've used inline implementation of the member functions here, for brevity's sake - you could equally implement A.classBSays() and B.f() in separate A.cpp and B.cpp files if you wanted.

In this example, the class BDelegate is an abstract base class (ABC), equivalent to your BDelegate protocol. By containing only pure virtual member functions (functions preceded with the keyword virtual and with the =0 suffix), it forces its subclasses to provide implementations for those methods, much as using a @required tag (or no tag) does in an Objective-C protocol. The fact that BDelegate contains only such functions is what makes it an ABC.

You can emulate the Objective-C @optional tag by specifying an empty body for the function in your ABC, which means that subclasses are not required to implement it (since it is implemented in the ABC). For example, you could emulate an optional foo method by modifying the BDelegate as follows:

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

Using that definition, the class A could choose whether to provide a definition for foo or not, as is desired. Note however that this is not exactly equivalent to the Objective-C @optional notation, because A will still inherit BDelegate's foo method if it doesn't provide it's own override. With the Objective-C protocol, on the other hand, A would have no such method at all unless it explicitly implements it itself.

A more thorough introduction to the subject is available here.

like image 131
Mac Avatar answered Nov 04 '22 09:11

Mac