I'm used to using Objective-C protocols in my code; they're incredible for a lot of things. However, in C++ I'm not sure how to accomplish the same thing. Here's an example:
Table view, which has a function setDelegate(Protocol *delegate)
Delegate of class Class, but implementing the protocol 'Protocol'
Delegate of class Class2, also implementing 'Protocol'
setDelegate(objOfClass) and setDelegate(objOfClass2) are both valid
In Obj-C this is simple enough, but I can't figure out how to do it in C++. Is it even possible?
Basically, instead of "Protocol" think "base class with pure virtual functions", sometimes called an interface in other languages.
class Protocol
{
public:
virtual void Foo() = 0;
};
class Class : public Protocol
{
public:
void Foo() { }
};
class Class2 : public Protocol
{
public:
void Foo() { }
};
class TableView
{
public:
void setDelegate(Protocol* proto) { }
};
Related
As you will soon see, I am not a c++ developer and for this problem I am working on c++ is my only option. I don't mind learning, so just some guidance would be appreciated.
I have a panel class as follows:
class Panel {
... // Methods that implement Panel
virtual void draw() = 0;
... // Other methods to implement Panel
}
And I want two varieties of it so I create two interfaces
class Foo {
virtual void foo() = 0;
}
class Bar: public Foo {
virtual void bar() = 0;
}
I want to pass the implementing class of Foo to other classes and have them only be able to call the method foo, and the same for Bar.
In other languages I could create the class that implements Foo as:
class FooPanel : public Panel, implements Foo{ ... }
or
class BarPanel : public Panel, implments Bar { ... }
then I can pass into a method:
//method(..., foo* pFoo, ...); the signature
method(..., (Foo*)&barPanel, ...);
The only way I can see to accomplish this in c++ is to:
class FooPanel : public Panel {
virtual void foo() = 0;
}
then one has to pass the entire Panel and the implementer is capable of calling and Panel method.
Where can I look to get an idea of how this can be done?
What other languages (such as java) call "interfaces" is just an abstract base class in C++. So if you just replace the implements keyword with public virtual, it will work as you expect:
class FooPanel : public Panel, public virtual Foo { ... }
class BarPanel : public Panel, public virtual Bar { ... }
class MyInterface {
public:
virtual void someFunction()= 0;
};
class X: public MyInterface {
private:
virtual void doThis() {
printf("This X");
}
virtual void doThat() {
printf("That X");
}
public:
void someFunction() {
doThis();
doThat();
}
};
class Y: public MyInterface, private X {
private:
void doThat() {
printf("That Y");
}
};
MyInterface *iface= new Y();
Y->someFunction();
Coming from Java's flavor of OOP, I am trying to wrap my head around the OOP model of C++. I have read this: http://www.gotw.ca/publications/mill18.htm for suggestions how to design interfaces in C++. The above code is a direct application (or a slight variation thereof) of the rule the author expounds. My question is, is the code above going to produce "This X" followed by "That Y"? What I find confusing is that the author recommends using virtual in conjunction with private. My reasoning is, if a function is private, how are we to override it at all?
In the above code, it is granted that Y can be used as the right-hand-side of the assignment, since we derive publicly from the interface. When we call someFunction() on it, since we do not explicitly provide any implementation inside class Y, is it going to use the implementation from class X? Then, provided it does, it looks at doThat() and again uses Ys implementation of it?
The code has a few problems. Here is a working example:
class MyInterface
{
public:
virtual ~MyInterface() { }
virtual void someFunction() = 0;
};
class X : public MyInterface
{
private:
virtual void doThis()
{
printf("This X\n");
}
virtual void doThat()
{
printf("That X\n");
}
public:
void someFunction()
{
doThis();
doThat();
}
};
class Y : public X
{
private:
void doThat()
{
printf("That Y\n");
}
};
int main()
{
MyInterface *iface = new Y();
iface->someFunction();
delete iface;
}
Explanations
You need to use class Y : public X to be able to use the implementation of void X::someFunction()
Unfortunately there is no real interface in C++ and there is only a workaround using pure virtual class. This workaround with two parents has it's own limitations (see bellow). And therefore it is also a good idea to add a destructor to interface definition.
When you use class Y: public MyInterface, private X you need to provide a custom implementation of MyInterface::someFunction(). You have have two parent classes and someFunction() in both parents (X and MyInterface). This is necessary even when there is only one implementation of function. Therefore you need to specify which parent class 'implementation' will be used. Error:
'Y': cannot instantiate abstract class
You also get a error when you remove the interface (try to use the interface from X). The reason is simple, when X is private, the implementation is not public and can not be used as a interface.
'type cast': conversion from 'Y *' to 'MyInterface *' exists, but is inaccessible
You are using class as type in Y->someFunction();
I have no idea, why you can override a private virtual function. I mostly work in C# now and this 'feature' of C++ is something I do not get. You are right, that this should be bad code, but it work (at least in Visual Studio 2017).
I would also like to know, why this is not considered as error/incorrect code construction.
Supposing a general player that will notify certain events to certain objects of classes. I create a base class with some virtual functions guaranteed to exist in the derived:
class PlayEventsReceiver{
virtual void StartPlay()=0;
virtual void StopPlay()=0;
};
I would derive from PlayEventsReceiver the classes interested in such "signals"
class FooPlayer:public PlayEventsReceiver{
void StartPlay(){...}
void StopPlay(){...}
};
But if I wanted, rather than inheriting, implementing the signaling mechanism as a property, like this:
class BarPlayer{
PlayEventsReceiver receiver;
};
Is it possible to implement the pure virtual functions somehow inside the class BarPlayer in a clean way and not creating intermediate derived classes?
If you don't have a derived class then the compiler has nowhere to put its functions. If you are looking for something clean then creating an explicit derived class is probably as clean as it gets.
You can't escape the fact that somewhere you need to supply the function implementations.
However, it seems you can do this anonymously by creating an unnamed class/struct. But it is not avoiding creating a derived class because an anonymous derived class is still being created:
// public interface so I use struct
struct PlayEventsReceiver {
virtual void StartPlay() = 0;
virtual void StopPlay() = 0;
};
class BarPlayer {
public:
struct : PlayEventsReceiver {
void StartPlay() override
{
std::cout << "Start Play\n";
}
void StopPlay() override
{
std::cout << "Stop Play\n";
}
} receiver;
};
int main()
{
BarPlayer bp;
bp.receiver.StartPlay();
}
I'm writing a C++ library for optimization, and I've encountered a curious issue with contra-variant types.
So, I define a hierarchy of "functions", based on what information they can compute.
class Function {
public:
double value()=0;
}
class DifferentiableFunction : public Function {
public:
const double* gradient()=0;
}
class TwiceDifferentiableFunction : public DifferentiableFunction {
public:
const double* hessian()=0;
}
Which is all well and good, but now I want to define interfaces for the optimizers. For example, some optimizers require gradient information, or hessian information in order to optimize, and some don't. So the types of the optimizers are contravariant to the types of the functions.
class HessianOptimizer {
public:
set_function(TwiceDifferentiableFunction* f)=0;
}
class GradientOptimizer : public HessianOptimizer {
public:
set_function(DifferentiableFunction* f)=0;
}
class Optimizer: public GradientOptimizer {
public:
set_function(TwiceDifferentiableFunction* f)=0;
}
Which I suppose makes sense from a type theoretic perspective, but the thing that is weird about it is that usually when people want to extend code, they will inherit the already existing classes. So for example, if someone else was using this library, and they wanted to create a new type of optimizer that requires more information than the hessian, they might create a class like
class ThriceDifferentiableFunction: public TwiceDifferentiableFunction }
public:
const double* thirdderivative()=0;
}
But then to create the corresponding optimizer class, we would have to make HessianOptimizer extend ThirdOrderOptimizer. But the library user would have to modify the library to do so! So while we can add on the ThriceDifferentiableFunction without having to modify the library, it seems like the contravariant types lose this property. This seems to just be an artifact of the fact the classes declare their parent types rather than their children types.
But how are you supposed to deal with this? Is there any way to do it nicely?
Since they're just interfaces, you don't have to be afraid of multiple inheritance with them. Why not make the optimiser types siblings instead of descendants?
class OptimizerBase
{
// Common stuff goes here
};
class HessianOptimizer : virtual public OptimizerBase {
public:
virtual set_function(TwiceDifferentiableFunction* f)=0;
}
class GradientOptimizer : virtual public OptimizerBase {
public:
virtual set_function(DifferentiableFunction* f)=0;
}
class Optimizer : virtual public OptimizerBase {
public:
virtual set_function(TwiceDifferentiableFunction* f)=0;
}
// impl
class MyGradientOptimizer : virtual public GradientOptimizer, virtual public HessianOptimizer
{
// ...
};
For example, when creating a class library, I would like to specify an internal API and a public API for each classes, so I can hide some details from the user. The internal API would be used by other classes in the library, and the public API would be used by the library user.
Is it possible?
In C++, interface could mean many things. It could mean pure virtual functions that you implement in the derived classes, as in the following example,
class Interface
{
public:
virtual void f() = 0 ;
};
class Implementation : public Interface
{
public:
virtual void f() {}
};
--
Or it could mean just public functions in your class:
class A
{
public:
void f() {} //public function - an interface that the outside world can
//use to talk to your class.
};
You can use either of these and can make use of access-specifiers ( public, protected, private) to make your interfaces public or internal/private!
Kind of.
Some libraries use friend classes/functions for this. Each class declares other classes as friends if they need access to more than the "public" interface:
class Car {
friend class Mechanic;
private:
Engine engine;
};
class Mechanic {
// something involving Car::engine...
};
It's not very pretty, but it works.
Another approach that might work for you is the pimpl (pointer-to-implementation) idiom:
class CarImpl; // declaration only
class Car {
private:
CarImpl *impl;
public:
CarImpl *getImpl(); // doesn't strictly belong in the pimpl pattern
// methods that simply call the corresponding methods on impl
};
The internal interface can be accessed through a getImpl() call. You would put the CarImpl declaration in a header file that is clearly marked as internal, so clients won't access it. For example, you could put such headers in a subdirectory called internal.
The obvious drawback is that the Car class has a bunch of trivial methods that you have to implement.
A third approach, that I do not recommend, is inheritance:
class Car {
public:
virtual void start() = 0;
static Car *create();
};
And in an internal header:
class CarImpl : public Car {
public:
virtual void start();
};
The Car class only exposes the public interface; to get access to the internal interface, internal code needs to do a downcast to CarImpl. This is ugly.
You can use many tricks to grant friendship or an "extended" interface to a given few, however it is soon cumbersome.
The simplest way to separate the external interface from the internal interface... is to have two interfaces, thus two classes.
If you take a peek at the set of Design Patterns proposed by the GoF, you'll notice the Proxy pattern.
You can use this by not exposing the class to the exterior of your library, but instead exposing a Proxy, in which you wrap the class, and which only exposes a subset of its interface.
class MyClass
{
public:
void foo();
void bar();
void printDebugInfo();
void test();
};
class MyClassProxy
{
public:
MyClassProxy(std::unique_ptr<MyClass> ptr): _ptr(ptr) {}
void foo() { _ptr->foo(); }
void bar() { _ptr->bar(); }
private:
std::unique_ptr<MyClass> _ptr;
};
I personally find this design rather clean. No down-casting, No subtle inheritance trick, No friendship list longer than my arm.
I'm not quite sure what you're asking, but if you have an abstract class defined:
class Loggable { ... };
You can inherit from it privately, like this:
class User : private Loggable { ... };
The class User now has the members of Loggable, but they are private.
Please see the C++ FAQ lite.
There is a number of ways to approach this. One is runtime polymorphism:
struct widget {
virtual debug_info diagnose() = 0;
virtual void draw() = 0;
};
struct window {
virtual void draw() = 0;
};
struct view : public window, public widget {
void draw();
debug_info diagnose(); // internal
};
Or with compile-time polymorphism:
struct view {
void draw();
debug_info diagnose(); // internal
};
template<class W>
void do_it(W window)
{
widget.draw();
}
template<class W>
void diagnose_it(W widget)
{
debug_info d = widget.diagnose();
}
Another approach is to expose private members to specific functions or classes:
struct widget {
virtual void draw() = 0;
};
struct view : public widget {
friend void diagnose_widget(widget w);
void draw();
private:
debug_info diagnose();
};
// internal
debug_info diagnose_widget(widget w)
{
debug_info d = w.diagnose();
}
A C++ class has 3 levels of protection: public, protected and private. Public things are accessible to everybody, protected only to descendant -- and then for themselves and not for other descendants --, private for the class and its friend.
Thus friendship is the only way to grant more than public access to a class/function which isn't a descendant, and it grants full access, which isn't always convenient.
An heavy solution which I've used with success was to write a wrapper which was a friend of the main class, and then provided additional access to its own friends (which were the only one able to construct the wrapper). I'm not really recommending it, it is tedious, but it could be useful if you have such a need.
class Main {
public:
...
private: // but wrapped
void foo();
protected:
...
private: // and not wrapped
void bar();
};
class Wrapper {
pubic:
void foo() { wrapped.foo(); }
private:
Wrapper(Main& m) : wrapped(ma) {}
Main& wrapped;
friend void qux(Main&);
};
void qux(Main& m) {
Wrapper mwrapped(m)
mwrapped.foo();
// still can't access bar
}