Trouble with multiple inheritance - c++

I'm trying to come up with an abstraction for a game framework and one approach is to create, for example, a graphics and audio class, these are the interfaces used by your games, and you derive specific implementations for your target platforms ( desktop/mobile/console ).
I have some example code of the idea here:
#include <iostream>
#include <string>
using namespace std;
struct Graphics
{
virtual ~Graphics() {}
virtual void Rect() {}
};
struct Text
{
virtual ~Text() {}
virtual void Print(string s) {}
};
struct IosGraphics : public Graphics
{
void Rect() { cout << "[]"; }
};
struct IosText : public Text
{
void Print(string s) { cout << s << endl; }
};
struct Output : public Graphics, public Text
{
};
struct IosOutput : public Output, public IosGraphics, public IosText
{
};
int main()
{
Output * output = new IosOutput();
output->Rect(); // this calling Graphics::Rect not IosGraphics::Rect
output->Print("Hello World!"); // this calling Text::Print not IosText::Print
cin.get();
}
The problem is that output is using the Text::Print instead of IosText::Print, I wonder if this is related to the diamond problem and I might have to use virtual inheritance or something. Any help is greatly appreciated.

"The diamond problem" isn't a problem, it's a symptom of not understanding the distinction between virtual and non-virtual inheritance. In the code above, the class Output has two base classes of type Graphics, one from Output and one from IosGraphics. It also has two base classes of type Text, one from Output and one from IosText. So output->Print("Hello, World!) calls the implementation of Print() in its base, that is, it calls Text::Print(). It doesn't know anything about IosGraphics::Print().
If you change IosGraphics to have Graphics as a virtual base, and change IosText to have Text as a virtual base, and change Output to have Graphics and Text as virtual bases, then things will do what you want because of the Dominance rule. Output doesn't override Rect() but IosGraphics does, so virtual calls to Output->Rect() go to IosGraphics::Rect(), and similarly for Text::Print().
I know, that sounds like magic. The rule is a bit weird, but it works. Try it.

In general, avoid multiple implementation inheritance at all costs. In your case, IosOutput has two copies of Graphics and Text in it, which is causing the problem.
The best solution is, however, not to use inheritance at all, but instead use membership -- IosOutput has members of type IosGraphics and IosText, and those may legitimately inherit from a more abstract Graphics and Text.
Also, consider interfaces -- classes with only pure virtual methods as an alternative solution.

Related

Modifying class behavior depending on property using if() is code smell or not?

I have a class representing some parameter. The parameter can be number, array, enum or bitfield - this is the param type. The behavior is slightly different between these types, so they are subclasses of paramBase class. The parameter can be stored in RAM or be static (i.e. hardcoded in some way, currently saved in a file).
void read() implemented in paramBase and uses template method pattern to implement reading for any param type, but this works only for RAM storage. If parameter is static then read() must be completely different (i.e. read from file).
A straightforward solution can be further subclassing like paramArrayStatic, paramNumberStatic, etc. (it will be 8 subclasses).
The difference between paramArray and paramArrayStatic is basically only in the read() method, so a straightforward solution will lead to code duplication.
Also I can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
class paramBase
{
public:
virtual paramType_t type() = 0;
paramStorage_t storage();
virtual someDefaultImplementedMethod()
{
//default implementation
}
void read()
{
//template method pattern
m_prop1 = blablabla;
someDefaultImplementedMethod();
}
protected:
paramStorage_t m_storage;
int m_prop1;
int m_prop2;
};
class paramArray: public paramBase
{
public:
virtual paramType_t type()
{
return PT_ARRAY;
}
virtual someDefaultImplementedMethod()
{
//overriding default implementation of base
//i.e. modify templated read() method behavior
}
protected:
int m_additional_prop1;
int m_additional_prop2;
};
In the end, I have 4 subclasses of base and I need to modify behavior of read() by static/non_static modificator.
How do I solve this without code duplication and code smell? Is the condition if( m_storage==static ) in read() is code smell or not?
You never have to duplicate code: just only re-implement that single method read. If you need to use it from pointers to the base class, virtual does just that. If you have common code between that 8 read method (or just between some of them), put it in a common middle layer.
If you want to make it clear that the class might not use the method at the base level, you can make it abstract, the add a ninth subclass for the RAM case.
Having a huge switch calling 9 different read methods in the same class seems far worse to me.
Straightforward solution can be furhter subclassing like paramArrayStatic, paramNumberStatic..etc. i.e. totally it will be 8 subclasses. Difference between paramArray and paramArrayStatic is basically only in read() method, so straightforward solution will lead to code duplication.
I agree. Creating a class that overrides the behaviour in such a significant way would be in violation of the SOLID principles (specifically the LSP part).
Also i can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
Who decides that this is code smell? It seems most expressive, and sensible to me.
Stop worrying so much about code smells, and start questioning the expressiveness of your options...
SigmaN,
For your simple example I would not worry about the control coupling in the read method. It is often better to have clear and maintainable code versus code that is strictly decoupled.
The general idea of your questions seems to be about decoupling the source of a value from the business logic for that value. Oftentimes, a good strategy is creating an interface as an ABC and then taking an instance on the the ctor. Here is a very simple example.
class ReadValue
{
public:
virtual int32_t readValue(std::string & value) = 0;
};
class DatabaseReadValue::public ReadValue
{
public:
virtual int32_t readValue(std:string & value) override; // read from the database
}
class XMLReadValue::public ReadValue
{
public:
virtual int32_t readValue(std::string & value) override; // read from XML file
}
class Parameter
{
public:
Parameter(ReadValue & readValueObj): readValueObj_(readValueObj) {}
int32_t read() { return(readValueObj_.readValue(value_)); }
ReadValue & readValueObj_;
std::string value_;
}
Oftentimes, the idea will be used in a template class rather than using inheritance. The gist is the same however.
The idea is related several Design Patterns depending on the details. Bridge, Adapter, Factory, Abstract Factory, PIMPL.
https://en.wikipedia.org/wiki/Software_design_pattern
--Matt
My problem is solved in this way:
//public interface and basic functionality
class base
{
public:
virtual void arraySize() //part of interface
{
printf("base arraySize()\n");
}
//template method read
int read()
{
readImpl();
}
protected:
virtual void readImpl() = 0;
};
//only base functionality of array is here. no read implementation!
class array : public base
{
public:
virtual void arraySize()
{
printf("array arraySize()\n");
}
};
//implement static read for array
class stat_array : public array
{
public:
void readImpl()
{
printf("stat_array read() \n");
}
};
//implement non static read for array
class nostat_array : public array
{
public:
void readImpl()
{
printf("nostat_array read() \n");
}
};
//test
stat_array statAr;
nostat_array nonstatAr;
base *statArPtr = &statAr;
base *nonstatArPtr = &nonstatAr;
void main()
{
statArPtr->read();
nonstatArPtr->read();
}

Draw on canvas from within C++ XPCOM code

Is it possible to draw on element from C++ XPCOM add-on?
Previously (long time ago probably) one could get an object of nsIDOMCanvasRenderingContext2D interface and use ti's method PutImageData_explicit in order to draw image on canvas. Nowadays, nsIDOMCanvasRenderingContext2D hides everything and I have no clue how to achieve this.
In general - is there a way to render a video (let's say obtained from remote host) by add-on on a web-page?
Any advice will be appreciated.
Thank you
There is PutImageData_explicit now. But that is a protected member.
You may cheat the system and break the encapsulation for your purposes, e.g. by deriving and downcasting (and now protected members are all yours).
Or do it the hard way, and use PutImageData while having to mess around with ImageData and ErrorResult.
Downcasting to get to a protected member:
#include <string>
#include <iostream>
class Base {
protected:
std::string myName() {
return "Base";
}
};
class Derived : public Base {
public:
std::string myName() {
return Base::myName();
}
};
int main() {
Base *base = new Base();
Derived* derived = static_cast<Derived*>(base);
std::cout << derived->myName() << std::endl;
delete base;
return 0;
}
PS: This works, because this still holds true sizeof(Base) == sizeof(Derived). You really don't want to modify the size, e.g. by adding data members or such, unless you're a fan of segfault and heap corruption ;)

Enforcing contract on concrete instances of an abstact hierarcy

I'm lost and in need of some divine guidance.
First things first: assume you have some nicely-neat interfaces:
class IProduct
{
public:
virtual void DoThings();
}
enum ProductType
{
...
}
class IProducer
{
public:
virtual IProduct* Produce( ProductType type );
}
class IConsumer
{
public:
virtual void Consume( IProduct* product );
}
Its plain simple yet: abstract factory, abstract consumer who will invoke interface, gladly provided by those freshly-spawned IProducts.
But here comes the tricky part.
Assume that there are two ( or more ) parallel concrete groups:
class ConcreteProducerA : public IProducer { ... }
class ConcreteConsumerA : public IConsumer { ... }
class ConcreteProductA : public IProduct { ... }
class ConcreteProducerB : public IProducer { ... }
class ConcreteConsumerB : public IConsumer { ... }
class ConcreteProductB : public IProduct { ... }
And those concretes are reeealy different things. Like a space-shuttle parts ( with a parts factory and a shuttle assembly line ) and bags of vegetables ( with a farm and .. idk, who whould consume those vegetables? ). Yet they have that thing in general: DoThings(). Pretend that it is, like, PackAndSend(), or Serialize(), or Dispose(), whatever you like. Nothing concrete, yet legit to base a hierarchy on.
But those still have more differences, than generalities. So those ConcreteConsumers tend to use them differently. So differently, that, in fact, they absolutely MUST be sure, that it is supposed concrete type.
So here is the problem: I'm forcing the users of that hierarchy to downcast IPoduct to ConcreteProduct in their virtual overrides right now. And thats bugging me hard. I feel I'm missing something: a big flaw in hierarchy, some lack of pattern knowledge, something.
I mean, I can make sure, that ConcreteConsumerB always recieves ConcreteProductB, but it's still a downcast. And would you ever use a framework, that always passes around (void*)'s and forces you to cast it to whenewer you think is gonna come at ya?
Solutions I've already considered:
Tunnel all conctrete interfeces into IProduct. But that product gona turn into uncontrollable blob, who can Eat(), BeEaten(), Launch(), Destroy() and whoever knows what else. So this solution seems nothing better than downcasting to me.
That DoThings() can probably be decoupled from IProduct into another handler, which will be able to accept all of the concretes (Visitor-like). That way IProduct can be removed and there will be separate concrete groups. But what if there is a SemiConcrete layer, which imlements some common functionality for those concrete groups? Like labeling, morphing, massaging, whatever. Plus when there will be need to add another concrete group I'll be forced to change that visitor(s), which kinda increases coupling.
(ab)Use templates. That seems wise at the moment. Something along the lines of
template < typename _IProduct >
class IConcreteProducer : public IProducer
{
public:
virtual _IProduct* Produce( _IProduct::Type type ) = 0;
virtual _IProduct::Type DeduceType( ProductType type ) = 0;
virtual IProduct* Produce( ProductType type )
{
return IConcreteProducer<typename _IProduct>::Produce( DeduceType( type ) );
}
}
template < typename _IProduct >
class IConcreteConsumer : public IConsumer
{
public:
virtual void Consume( _IProduct* product ) = 0;
virtual void Consume( IProduct* product )
{
IConcreteConsumer<typename _IProduct>::Consume( (_IProduct*)product );
}
}
This way I'm in control of that downcast, but it is stil present.
Anyways, does this problem sound familiar to someone? Somebody seen it solved, or maybe heroicaly solved it himself? C++ solution would be awesome, but I think any staticaly-typed language will suffice.
Yet they have that thing in general: DoThings(). Pretend that it is,
like, PackAndSend(), or Serialize(), or Dispose(), whatever you like.
Nothing concrete, yet legit to base a hierarchy on.
Just because they can be in some hierarchy, doesn't mean they should. They are unrelated. I can't even fathom what value you are adding to whatever code base by generalizing shuttles and vegetables. If it doesn't add benefit to the users, then you are likely just making things more convoluted on yourself.
I would expect to see interfaces like the below. Notice they don't inherit from anything. If you have shared code, write simpler dumb concrete classes that people can reuse by composition.
template<typename T>
class Producer {
public:
virtual ~Producer() {}
virtual std::auto_ptr<T> produce() = 0;
};
template<typename T>
class Consumer {
public:
virtual ~Consumer() {}
virtual void consume(std::auto_ptr<T> val) = 0;
};
Then I'd expect to see concrete functions to create these from various sources.
typedef Producer<Shuttle> ShuttleProducer;
typedef Consumer<Shuttle> ShuttleConsumer;
std::auto_ptr<ShuttleProducer> GetShuttleProducerFromFile(...);
std::auto_ptr<ShuttleProducer> GetShuttleProducerFromTheWeb(...);
std::auto_ptr<ShuttleProducer> GetDefaultShuttleProducer();
There probably isn't a pattern for what you want to do, it is likely two patterns that you are smooshing (technical term) together. You didn't betray why these things should be sharing a code base, so we can only guess.
In the more complicated scenarios, you'll want to strictly separate use from creation though. It is perfectly valid to have different interfaces that look sort of similar, but are used differently.
class Foo {
public:
virtual ~Foo() {}
virtual void doStuff() = 0;
virtual void metamorphose() = 0;
};
class Fu {
public:
virtual ~Fu() {}
virtual void doStuff() = 0;
virtual void transmorgrify() = 0;
};
One possibility is to introduce a second layer to hot hierarchy. Derive IShuttle from IProduct, and derive that group from it. Then add an IShuttleProducer that yields an IShuttle* instead of IProduct*. This is okay, because C++ allows covariant return types for virtual functions... so long as the the new return type derives from the original, it is still considered an override.
But your design probably needs some rethinking either way.

Dealing with functions in a class that should be broken down into functions for clarity?

How is this situation usually dealt with. For example, an object may need to do very specific things:
class Human
{
public:
void eat(Food food);
void drink(Liquid liquid);
String talkTo(Human human);
}
Say that this is what this class is supposed to do, but to actually do these might result in functions that are well over 10,000 lines. So you would break them down. The problem is, many of those helper functions should not be called by anything other than the function they are serving. This makes the code confusing in a way. For example, chew(Food food); would be called by eat() but should not be called by a user of the class and probably should not be called anywhere else.
How are these cases dealt with generally. I was looking at some classes from a real video game that looked like this:
class CHeli (7 variables, 19 functions)
Variables list
CatalinaHasBeenShotDown
CatalinaHeliOn
NumScriptHelis
NumRandomHelis
TestForNewRandomHelisTimer
ScriptHeliOn
pHelis
Functions list
FindPointerToCatalinasHeli (void)
GenerateHeli (b)
CatalinaTakeOff (void)
ActivateHeli (b)
MakeCatalinaHeliFlyAway (void)
HasCatalinaBeenShotDown (void)
InitHelis (void)
UpdateHelis (void)
TestRocketCollision (P7CVector)
TestBulletCollision (P7CVectorP7CVectorP7CVector)
SpecialHeliPreRender (void)
SpawnFlyingComponent (i)
StartCatalinaFlyBy (void)
RemoveCatalinaHeli (void)
Render (void)
SetModelIndex (Ui)
PreRenderAlways (void)
ProcessControl (void)
PreRender (void)
All of these look like fairly high level functions, which mean their source code must be pretty lengthy. What is good about this is that at a glance it is very clear what this class can do and the class looks easy to use. However, the code for these functions might be quite large.
What should a programmer do in these cases; what is proper practice for these types of situations.
For example, chew(Food food); would be called by eat() but should not be called by a user of the class and probably should not be called anywhere else.
Then either make chew a private or protected member function, or a freestanding function in an anonymous namespace inside the eat implementation module:
// eat.cc
// details of digestion
namespace {
void chew(Human &subject, Food &food)
{
while (!food.mushy())
subject.move_jaws();
}
}
void Human::eat(Food &food)
{
chew(*this, food);
swallow(*this, food);
}
The benefits of this approach compared to private member functions is that the implementation of eat can be changed without the header changing (requiring recompilation of client code). The drawback is that the function cannot be called by any function outside of its module, so it can't be shared by multiple member functions unless they share an implementation file, and that it can't access private parts of the class directly.
The drawback compared to protected member functions is that derived classes can't call chew directly.
The implementation of one member function is allowed to be split in whatever way you want.
A popular option is to use private member functions:
struct Human
{
void eat();
private:
void chew(...);
void eat_spinach();
...
};
or to use the Pimpl idiom:
struct Human
{
void eat();
private:
struct impl;
std::unique_ptr<impl> p_impl;
};
struct Human::impl { ... };
However, as soon as the complexity of eat goes up, you surely don't want a collection of private methods accumulating (be it inside a Pimpl class or inside a private section).
So you want to break down the behavior. You can use classes:
struct SpinachEater
{
void eat_spinach();
private:
// Helpers for eating spinach
};
...
void Human::eat(Aliment* e)
{
if (e->isSpinach()) // Use your favorite dispatch method here
// Factories, or some sort of polymorphism
// are possible ideas.
{
SpinachEater eater;
eater.eat_spinach();
}
...
}
with the basic principles:
Keep it simple
One class one responsibility
Never duplicate code
Edit: A slightly better illustration, showing a possible split into classes:
struct Aliment;
struct Human
{
void eat(Aliment* e);
private:
void process(Aliment* e);
void chew();
void swallow();
void throw_up();
};
// Everything below is in an implementation file
// As the code grows, it can of course be split into several
// implementation files.
struct AlimentProcessor
{
virtual ~AlimentProcessor() {}
virtual process() {}
};
struct VegetableProcessor : AlimentProcessor
{
private:
virtual process() { std::cout << "Eeek\n"; }
};
struct MeatProcessor
{
private:
virtual process() { std::cout << "Hmmm\n"; }
};
// Use your favorite dispatch method here.
// There are many ways to escape the use of dynamic_cast,
// especially if the number of aliments is expected to grow.
std::unique_ptr<AlimentProcessor> Factory(Aliment* e)
{
typedef std::unique_ptr<AlimentProcessor> Handle;
if (dynamic_cast<Vegetable*>(e))
return Handle(new VegetableProcessor);
else if (dynamic_cast<Meat*>(e))
return Handle(new MeatProcessor);
else
return Handle(new AlimentProcessor);
};
void Human::eat(Aliment* e)
{
this->process(e);
this->chew();
if (e->isGood()) this->swallow();
else this->throw_up();
}
void Human::process(Aliment* e)
{
Factory(e)->process();
}
One possibility is to (perhaps privately) compose the Human of smaller objects that each do a smaller part of the work. So, you might have a Stomach object. Human::eat(Food food) would delegate to this->stomach.digest(food), returning a DigestedFood object, which the Human::eat(Food food) function processed further.
Function decomposition is something that is learnt from experience, and it usually implies type decomposition at the same time. If your functions become too large there are different things that can be done, which is best for a particular case depends on the problem at hand.
separate functionality into private functions
This makes more sense when the functions have to access quite a bit of state from the object, and if they can be used as building blocks for one or more of the public functions
decompose the class into different subclasses that have different responsibilities
In some cases a part of the work falls naturally into its own little subproblem, then the higher level functions can be implemented in terms of calls to the internal subobjects (usually members of the type).
Because the domain that you are trying to model can be interpreted in quite a number of different ways I fear trying to provide a sensible breakdown, but you could imagine that you had a mouth subobject in Human that you could use to ingest food or drink. Inside the mouth subobject you could have functions open, chew, swallow...

calling a function from a set of overloads depending on the dynamic type of an object

I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.