How would someone solve such a problem with classes and type as least as possible code?
Here is what I have
Base interface for everything
class IWindow
{
public:
virtual void Refresh() = 0;
// another 100 virtual methods
// ...
};
This interface is used inside a library that has no idea about the concrete implementation.
Here is a version of the concrete implementation
class ConcreteWindow : public IWindow
{
public:
void Refresh() override {}
/// the other 100 overridden methods
};
Now we have another interface that adds some additional methods and also used inside that library.
class IDBDetail : public IWindow
{
public:
virtual void DoDetail() = 0;
};
and here is the main problem, when we create the concrete inmplementation for it
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
void DoDetail() {}
};
of course the concrete class IGDBDetailWrapper is abstract as well because it doesn't implement those 100 methods, but I don't wanna do that, I'd like just to reuse the implementation from ConcreteWindow, they are all working with the same window handle but this won't compile of course.
I can copy/paste those 100 methods from ConcreteWindow into IGDBDetailWrapper, but that's an overkill, cause I might have another 10 such new interfaces and concrete implementations.
What other pattern can I use here that would help solve the question and not re-implement those 100 methods again and again?
Thx
Your design is running into diamond problem.
Now we have another interface that adds some additional methods and
also used inside that library.
class IDBDetail : public IWindow {
public:
virtual void DoDetail() = 0;
};
From the description of your IDBDetail interface looks like IDBDetail should not inherit from IWindow. If its just about adding additional functionality then IDBDetail need not be a IWindow. It just needs to understand the IWindow. For example in order to make a monkey do a special things, a trainer need not be a monkey.
Decorator pattern may be what you are looking for.
First, if you are using Visual Studio there are refactoring tools that can help you with that automating what could be otherwise a tedious task, second:
To me is much pointless doing the same:
class IDBDetail : public IWindow
{
public:
virtual void DoDetail() = 0;
};
I would do that instead
class IDBDetail
{
public:
virtual void DoDetail() = 0;
};
Interfaces should be used to abstract away responsibilities, so cluttering a Interface with already hundreds of methods with additional methods is a symptom of bad design.
However you could leverage composition one time for all, so you create one time a class that resolve the problem for your, and you can later reuse that
class IDBDetailWithConcreteWindow: public IDBDetail{
IWindow * concreteWindow;
public:
IDBDetailWithConcreteWindow(IWindow * window){
concreteWindow = window;
}
void Refresh() override{
concreteWindow->Refresh();
}
}
And finally in any derived class you have just to implement methods from IDBDetail
IGDBDetailWrapper: public IDBDetailWithConcreteWindow{
public:
void DoDetail() override { }
}
The advantage with this solution is that if you have external constraints (like a bad designed pre-existing code base) you can still use it, while the upper solution will not work if you cannot change the IDBDetail interface.
#bashrc is right, but it should be possible to solve the problem with virtual inheritance:
class ConcreteWindow : public virtual IWindow {...}
class IDBDetail : public virtual IWindow {...}
This Wikipedia article on virtual inheritance states the solution as well.
You can use virtual inheritance. If we ignore fact should IDBDetail inherit from IWindow or not, we could use virtual inheritance to solve problem with current architecture:
class IWindow
{
public:
virtual void Refresh() = 0;
// another 100 virtual methods
// ...
};
class ConcreteWindow : virtual public IWindow
{
public:
void Refresh() override {}
/// the other 100 overridden methods
};
class IDBDetail : virtual public IWindow
{
public:
virtual void DoDetail() = 0;
};
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
void DoDetail() {}
};
Now compiler will use implementation for your 101 abstract method from ConcreteWindow
You have to override all the methods in abstract class, there is no other way. Actually you shouldn't create an abstract class of 100 methods here and that's it. Perhaps You can divide it in some smaller abstract classes? However, in this case IDBDetail should not inherit after IWindow and IGBDDetailWrapper also shouldn't inherit after IWindow - and we are here.
It will not solve your problem, but at least you can redirect execution yourself:
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public:
virtual void DoDetail() override { /*work here*/ }
virtual void Refresh() override { ConcreteWindow::Refresh(); }
//another 100 methods
};
You can make the block of such redirections as a compiler #DEFINE and repeat it as many times as you want.
Related
Please Consider:
IReferenceCounting is a pure abstract class, with methods AddRef and RemoveRef
virtual void AddRef() noexcept = 0;
virtual void RemoveRef() noexcept = 0;
I did not build this class, nor can I change it.
Now I have another class, which I did build, called ISoundComponent that inherits from IReferenceCounting. Class ISoundComponent is also abstract (for a start it doesn't contain a definition for AddRef or Release).
As every component that inherits from IReferenceCounted will need to implement AddRef and RemoveRef, there exists ReferenceCountedImpl, which inherits from IReferenceCounted. I did not build this class and I cannot change it.
Finally, I have another class I did build, say SoundDiagnostics, which inherits from ISoundComponent and ReferenceCountedImpl
Many have you have already seen it - I have a diamond inheritance problem. By not providing my own AddRef and RemoveRef, and instead using ReferenceCountedImpl, means I would need ISoundComponent and ReferenceCountedImpl to inherit virtually from IReferenceCounted... correct?
Unfortunately I cannot edit ReferenceCountedImpl only ISoundComponent . This is because IReferenceCounting and ISoundComponent live across many projects in our codebase but ReferenceCountedImpl lives inside only a single project (the same project SoundDiagnostics lives). This makes sense, as a project can decide on how it wants to implement the IReferenceCounting, and we should be able to reuse it inside different classes in that project.
Unfortunately, as I cannot go and edit ReferenceCountedImpl, I cannot build this, due to the diamond inheritance problem (SoundDiagnostics won't know whether to call ReferenceCountedImpl::AddRef or ISoundComponent ::AddRef).
I feel like I'm barking up the wrong tree, missing something obvious, getting caught up in the details of virtual inheritance and/or and my design is messed up. The codebase organization should be agnostic to this problem. Can anyone give me some guidance on how this should be architected? I don't think ReferenceCountedImpl inheriting virtually from IReferenceCounted is the solution - e.g. there are performance reasons to consider when doing this.
Interested to learn how to tackle this.
EDIT:
// available across all projects in code base
class IReferenceCounted
{
virtual void AddRef() = 0;
virtual void RemoveRef() = 0;
};
// available across a few select projects in the codebase (ones that wish to use some kind of sound component)
class ISoundComponent : public virtual IReferenceCounted
{
virtual void Play() const = 0;
};
// available within one specific project, SoundDiagnostics. I cannot modify this
class ReferenceCountedImpl : public IReferenceCounted
{
void AddRef() override
{
m_refcount++;
}
void RemoveRef() override
{
if (--m_refcount == 0)
{
delete this;
}
}
int m_refcount = 0;
};
// available within one specific project, SoundDiagnostics.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void RunDiagnostics()
{
}
};
// function within my SoundDiagnostics project
int main()
{
SoundDiagnostics soundDiagnostics;
return 0;
}
Trying to compile this will produce
object of abstract class type "SoundDiagnostics" is not allowed:
pure virtual function "IReferenceCounted::AddRef" has no overrider
pure virtual function "IReferenceCounted::RemoveRef" has no overrider
If ReferenceCountedImpl inherits virtually from IReferenceCounted then this code compiles successfully.
I tried to turn your description into code. It works.
class IReferenceCounting {
public:
virtual void AddRef() const noexcept = 0;
virtual void RemoveRef() const noexcept = 0;
};
class IComponentPublicHeader :public virtual IReferenceCounting {};
class ReferenceCountedImpl :public virtual IReferenceCounting {
public:
void AddRef() const noexcept override {};
void RemoveRef() const noexcept override {};
};
class MyAmazingClass : IComponentPublicHeader, ReferenceCountedImpl {
MyAmazingClass() {
AddRef();// ReferenceCountedImpl::AddRef
}
};
Update:I read your code snippet.If AddRef and RemoveRef is public,You can try to implement your class like this.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void AddRef() override
{
ReferenceCountedImpl::AddRef();
}
void RemoveRef() override
{
ReferenceCountedImpl::RemoveRef();
}
void RunDiagnostics()
{
}
};
If AddRef and RemoveRef is private,let ISoundComponent not inherit the IReferenceCounted.
class ISoundComponent
{
virtual void Play() const = 0;
};
I got problems formulating it precisely so I left more general description in the title (if you have more precise description of the problem, please comment, I'll edit the title).
The problem: Two classes AudioStream and VideoStream are derived from base class MediaStream which has some common for audio and video stream methods, but is not intended to be used as-is. Consequently, there are two classes AudioStreamSettings and VideoStreamSettings which are derived from MediaStreamSettings and passed to the constructors of their corresponding stream classes. MediaStreamSettings stores settings common for audio and video, and base class MediaStream accesses this data. The question is: what would be the best way to design this hierarchical relationship between base classes of streams and settings?
I can think of a quick solution like the following:
class MediaStream {
public:
MediaStream(const MediaStreamSettings& settings){
// do nothing, let derived classes initialize settings_
// note: I feel guilty for doing this...
}
virtual ~MediaStream(){}
protected:
std::shared_ptr<MediaStreamSettings> settings_;
};
class VideoStream : public MediaStream {
public:
VideoStream(const VideoStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<VideoStreamSettings>(settings);
}
void doSomething(){
int s1 = std::dynamic_pointer_cast<VideoStream, MediaStream>(settings_)->getVideoStreamSetting1();
...
}
};
class AudioStream : public MediaStream {
public:
AudioStream(const AudioStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<AudioStreamSettings>(settings);
}
}
To summarize I'm not comfortable with two things in this approach:
not initializing settings_ in base class (should I make it abstract to calm myself?)
using dynamic_pointer_cast every time I need to access settings in derived classes (should I make a method wrapper for this?)
One solution is to not store data in MediaStream and add a virtual method
virtual const MediaStreamSettings& GetMediaStreamSettings() const = 0;
Since MediaStream should not be used as-is, making it an abstract class should be acceptable (and desirable).
Thus providing implementation (which includes class members) is pointless.
class IMediaStream {
public:
virtual ~IMediaStream() {}
virtual void play() = 0;
virtual std::shared_ptr<MediaSettings> getSettings() = 0;
private:
IMediaStream() {}
};
template<Setting>
class MediaStream : public IMediaStream {
public:
MediaStream(const Setting& settings){
settings_ = std::make_shared<Setting>(settings);
}
virtual ~MediaStream() {}
virtual void play() override {
// Implementation here
}
virtual std::shared_ptr<MediaSettings> getSettings() override {
return std::dynamic_pointer_cast<Setting, MediaSettings>();
}
private:
std::shared_ptr<Setting> settings_;
}
// Alternatively you can inherit or specialize
// the template to add your implementation
typedef MediaStream<VideoStreamSettings> VideoStream;
typedef MediaStream<AudioStreamSettings> AudioStream;
I have a problem with interfaces and multiple inheritance. I hope to design my program such that one update call processes a variety of objects, with each behavioral 'building block' tucked away in a single function.
For example, I'd like to move a creature from point A to B in one place, regardless of whether it must perform pre/post move actions. But, my multiple inheritance scheme fails (below, with the bug rem'd), making me think I'd need to duplicate code somewhere.
Clearly I don't understand this well enough! (but I'm working hard to learn it)
Q1. Why can't IPhysics::Move 'see' Creature::Move(), in the CreatureAirborne class?
Q2. Am I completely missing the proper usage of interfaces and/or multiple inheritance? If so, any guidance is appreciated!
#include <deque>
#include <memory>
class IGameObject
{
public:
virtual ~IGameObject() {}
virtual void Update() = 0;
};
class IPhysics
{
public:
virtual ~IPhysics() {}
virtual void Move() = 0;
};
class IPhysicsFlight : public IPhysics
{
public:
virtual ~IPhysicsFlight() {}
virtual void Land() = 0;
virtual void TakeOff() = 0;
};
class Creature : public IGameObject, IPhysics
{
protected:
virtual void Move() {}
public:
Creature() {}
virtual ~Creature() {}
virtual void Update() {}
};
class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
virtual void Land() {}
virtual void TakeOff() {}
public:
CreatureAirborne() {}
virtual ~CreatureAirborne() {}
virtual void Update();
};
void CreatureAirborne::Update()
{
TakeOff();
Creature::Move();
Land();
}
int main()
{
std::deque<std::shared_ptr<Creature>> creatures;
std::shared_ptr<Creature> cow(new Creature);
creatures.push_back(cow);
// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'
// std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);
// creatures.push_back(butterfly);
for (auto i : creatures)
{
i->Update();
}
}
It's somewhat had to follow your hierarchy, but it looks correct evaluation on the compiler's part.
You don't have virtual inheritance anywhere, so CreatureAirborne will have duplicated base classes from some point. You will have two instances of IPhysics. Move, that is abstract from there is implemented on the Creature branch but remains abstract on IPhysicsFlight.
You can cure the situation by using virtual inheritance somewhere, or by implementing Move in descendant (say just calling the parent version where it exists).
I would look at things little differently
class CreatureAirborne : public IPhysicsFlight,Creature
While the code runs
new CreatureAirborne ()
The compiler will try to build IPhysicsFlight base class and Creature base class and the fact that IPhysics is a base class to both doesn't play any role rather than confusing.As far as compiler is concerned IPhysicsFlight is abstract and CreatureAirborne did not implement Move
The diamond issue will actually come into play when you do a
(new CreatureAirborne ())->Move()
There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?
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
}