For several graphic objects I inherit from QGraphicsLineItem, QGraphicsRectItem and so on.
class CustomLine : public QGraphicsLineItem{};
class CustomRect : public QGraphicsRectItem{};
Those objects are added to a container, a custom subclass of a QGraphicsScene "scene" that is meant for displaying and interacting with those items. this->scene->items() returns a list of QGraphicItem's: QList<QGraphicsItem* >
What I want to do is each custom object class to have the same custom interface methods, for example setModeX(). Then I could do stuff like:
Foreach (BaseItem *item, this->scene->items()){
item->setModeX(...);
}
But how do I achieve that?
If I make an interface like
class BaseItem{
public: setModeX(); [...]
private: Mode mode_;
}
and inherit
class CustomLine : public QGraphicsLineItem, BaseItem {};
So while the scene should only contain items based on BaseItem (not sure if this is really needed for this task), I first retrieve a list of objects of one of its 2 base classes, namely QGraphicsItem, and need to cast it to its other base class BaseItem to use the interface methods.
I will probably not be able to cast a CustomLine-item to BaseItem in the loop above, because it does not know about the other base class.
EDIT:
I use MinGW 4.8 32 bit (g++).
I noticed that when I start the foreach-loop, the items in my scene disappear (yet don't see the reason why)
Since scene is a QGraphicsScene, it only consists of QGraphicsItems. So you cannot directly iterate over scene as BaseItems as you show in your code. You have to iterate over each QGraphicsItem. You describe that you could downcast to your CustomLine and then upcast back to a BaseItem, but this only works if you know that all the items in the scene are lines. If scene contains other types of items, your technique would require you to iterate of each kind of item until you found a downcast that worked, and then cast it back to BaseItem.
QGraphicsItem
\ BaseItem
QGraphicsLineItem /
\ /
CustomLine
A simple solution would have been available to you if the Qt library had used virtual inheritance on QGraphicsItem. Then, you would simply need to use virtual inheritance on QGraphicsItem from BaseItem, and then down casting would have worked.
QGraphicsItem
/ \
QGraphicsLineItem BaseItem
\ /
CustomLineItem
Since Qt does not do so, you would either need to make custom changes to the Qt library, or code in your own conversion mechanism.
Assuming you are unwilling to make custom modifications to the Qt library itself, then one approach is to create a mapping between Qt's QGraphicsItem and your BaseItem. The mapping can be done within the constructor of your BaseItem, and undone from BaseItems destructor. To make undoing the mapping more efficient, you can also create a link from the BaseItem to the QGraphicsItem.
class BaseItem {
static std::unordered_map<QGraphicsItem *, BaseItem *> map;
QGraphicsItem *link_;
public:
BaseItem (QGraphicsItem *q) : link_(q) {
//...
map[q] = this;
}
virtual ~BaseItem () {
map.erase(link_);
//...
}
static BaseItem * getBaseItem (QGraphicsItem *q) {
std::unordered_map<QGraphicsItem *, BaseItem *>::iterator i;
if ((i = map.find(q)) == map.end()) return NULL;
return i->second;
}
//...
};
//...
std::unordered_map<QGraphicsItem *, BaseItem *> BaseItem::map;
In your derived classes, you would simply need to pass this to the BaseItem constructor.
class CustomLine : public QGraphicsLineItem, public BaseItem {
public:
CustomLine () : BaseItem(this) {
//...
};
//...
};
And then your loop would use the static BaseItem::getBaseItem() function to convert from a QGraphicsItem pointer to a BaseItem pointer. Thus, since there is no way to create a useable inheritance relationship between QGraphicsItem and BaseItem, their relationship is recorded in a table.
QGraphicsItem <-----------------. link
\ BaseItem <--' map
QGraphicsLineItem /
\ /
CustomLine
Should work just fine, but remember to declare the interface methods virtual in the base class, at least if you want polymorphic behavior.
Declare the functions that you want to exist in every derived class as virtual in the base class. A function that is defined as virtual in the base class can give a default implementation, but derived classes are free to override that implementation and provide their own. You can also declare that function "purely virtual" which means derived classes MUST provide an implementation for that particular function.
In either case, when calling that function on an instantiated object pointed to by a pointer of the base class, it will notice that the base class declared the function to be virtual and use a virtual table (vtable) to find which function to call (As in the base class' definition of the function, if it exists, or the derived classes version of the function).
It seems like there are some constraints on your problem that make this more of an issue than it should be. If you can't control the underlying pointers in your scene, but you know that each of those items inherits from BaseItem, then you can do a cast inside your for loop.
For instance, using the structure you have above:
Foreach (QGraphicsItem *item, this->scene){
((BaseItem*) item)->setModeX(...);
}
Of course, this is only if you can guarantee that the objects in your scene are derived from BaseItem.
CRTP to the rescue:
template <class D> class Base {
D& m_d;
public:
Base(D& derived) : m_d(d) { ... }
...
};
class CustomLine : public QGraphicsLine, Base<CustomLine> {
...
CustomLine() : Base(*this) { ... }
};
Related
I have a base model where I have implemented the virtual members of QAbstractItemModel. I then use my base model in my project as needed by deriving new classes with specifics.
class BaseModel : public QAbstractItemModel{
public:
...
protected:
QList<BaseItem*> list;
}
class DerivedModel : public BaseModel{
public:
...
}
class DerivedItem : public BaseItem{
public:
...
}
My derived model uses DerivedItem objects to store data which have some specifics that BaseItem doesn't have. They are stored in list. Methods in BaseModel uses objects in list as well.
My issues is because of this I have to type cast every time I access objects from list in the derived model. And I can't use macros like foreach.
Is there any tips or tricks I can use in this circumstance that will enable me to use macros and prevent me from type casting every time I access items from the list. Or is there another method (better practice) when making a common class to later derive from.
Thanks,
when BaseItem has virtual methods and DerivedItem does only overwrite the existing members of BaseItem you should be able to call
foreach(BaseItem* item, list){
item->foo();
}
because of polymorphism, item->foo() will call DerivedItem::foo() if it is of that type otherwise it will call BaseItem::foo()
I am implementing a visual tree in SFML. SFML contains two important drawing classes: sf::Drawable and sf::Transformable. It would be nice if these were bundled up together, but they are not. Many objects inherit from both, i.e.:
class SFML_GRAPHICS_API Text : public Drawable, public Transformable
class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
For my visual tree, I have a SceneNode class that inherits from Drawable and Transformable, and a draw function will call a private onDraw itself, and then its children. However, many SFML native classes, such as sf::Text, have a draw function that is private. So, I cannot create a class like
class Text: public sf::Text, public SceneNode
and then put it into the visual tree. For these native classes, I don't need them to have draw children anyway, I just want to be able to add them to the visual tree as leaf nodes. The crux of the problem is that each member of the visual tree needs to inherit from sf::Drawable and sf::Tranformable. I need to be able to define a type that inherits from both of these. If I define the dummy class
class LeafNode: public sf::Drawable, public sf::Tranformable { }
which appears to define the type I want. Then, SceneNode will contain std::vector<LeafNode*> m_children. When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
However the following code does not compile due to type incompatibility:
LeafNode * node = new sf::Text("PLAY", font, 20);
Ideally, I want to define something like
std::vector<sf::Drawable, sf::Transformable*> m_children
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
However, many SFML native classes, such as sf::Text, have a draw function that is private
That's not quite true. Since the sf::Drawable::draw function is protected, so is the draw method of sf::Text. It's one of the complex rules of C++.
So, I cannot create a class like
class Text: public sf::Text, public SceneNode
If you did you would have two sf::Drawable and sf::Transformable base classes in your hierarchy, one from sf::Text and one from SceneNode. That wouldn't be good.
When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
I would not recommend such design. Using dynamic_cast is usually a sign your software design is not so great. (I don't want to digress too much on this topic, google about that topic.)
But let's answer your fundamental question:
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
No. But you can do simpler things anyway.
Instead of having Text inheriting from both sf::Text and SceneNode, define you class as a wrapper. It can be as simple as:
class Text : public SceneNode {
sf::Text m_text;
public:
sf::Text& get() { return m_text; }
// Override SceneNode drawing method:
virtual void onDraw(RenderTarget& target) const
// Draw m_text:
target.draw(m_text);
}
};
There is two flaws with this quick wrapper, though. a) It doesn't use the transformable part of the SceneNode. b) Since the encapsulation is broken with get() there are two transformable modifiable by the user: the one from SceneNode and the one of sf::Text.
For a), the fix should be straightforward when you have fixed b). To fix b), you have to make the wrapper a little bit more complex: instead of having this ugly get(), write methods to set the properties of the underlying sf::Text that are not linked to sf::Transformable, e.g. setColor.
Without knowing anything about SMFL (which may provide better solutions) I think you can implement this vector. You only need to define your own pointer wrapper, which only accepts pointers to objects which inherits from more than one type:
template <class T1, class T2>
struct special_pointer_wrapper
{
T1* t1;
T2* t2;
template<class T>
special_pointer_wrapper(T* p)
: t1(dynamic_cast<T1*>(p))
, t2(dynamic_cast<T2*>(p))
{
if ((p1==0) || (p2==0))
throw "Error";
}
getT1 T1* () const { return t1; }
getT2 T2* () const { return t2; }
};
This class takes any pointer and ensures its pointed to type is derived from T1 and T2 (even if they seem to be totally unrelated). If its not a derived object it throws. With functions getT1() and getT2() it gives you access to pointers to both base classes.
Please note the construction may be slow due dynamic_cast but extraction of the types is O(1).
How should one approach composition instead of inheritance? Consider the following class:
class GameObject {...};
class Sprite {
public:
void changeImage(...);
};
class VisibleGameObject: public Sprite, public GameObject {};
class VisibleGameObject : public GameObject {
protected:
Sprite m_sprite;
};
The first VisibleGameObject class uses inheritance. Multiple inheritance. Does not looks good. Second one is what i would like to use, but it won't allow me to access Sprite's API like this:
VisibleGameObject man;
man.changeImage();
How can that be accomplished without inheritance (or code duplication)?
EDIT:
I do know I can just use inheritance or make m_sprite a public member and I can't access the Sprite class because it's private. That's the point, the question is about the best way to change a VisibleGameObject's Sprite, following the rules of data encapsulation.
I think you are still one step behing "composition over inheritance" mindset. The base class should know what to composite. To change image, you should change sprite instance, you shouldn't provide interface of composed instances. For example:
class GameObject {
public:
// you can choose public access or getters and setters, it's your choice
Sprite sprite;
PhysicalBody body;
};
object = GameObject();
object.sprite = graphicalSystem.getSpriteFromImage("image.png");
// or if you prefer setters and getters
object.setSprite(sprite);
More generally GameObject should contain instances (or pointers to instances, depends on your implementation) of base class Component. It makes sense to use inheritance in this case, because this way they can be in one storage like std::map. For example:
class Component {
// ...
};
class Sprite : public Component {
//...
};
class PhysicalBody : public Component {
//...
};
class GameObject {
protected:
std::map<std::string, Component*> components;
//...
public:
Component* getComponent(const std::string& name) const;
void setComponent(const std::string& name, Component* component);
//...
};
For component creation and rendering in main loop use Systems. For example GraphicalSystem knows all instances of Sprite it has created and while rendering it renders only sprites attached to some GameObject instance. Detached component can be garbage collected. Information about position and size might be part of the GameObject or it might be a component "physical".
The best way to understand it is to write your own prototype or to check existing implementations (Artemis, Unity 3D and many others). For more information see Cowboy programming: Evolve Your Hierarchy or try to find Entity/component system.
First of all, the alternative for composition is private inheritance (and not public one) since both model a has-a relationship.
The important question is how can we expose Sprite public members (e.g. changeImage) to VisibleGameObject clients? I present the 4 methods that I know:
(Private) inheritance
I understand that you want to avoid (multiple) inheritance, but for the sake of completeness, I present one suggestion based on private inheritance:
class VisibleGameObject: private Sprite, public GameObject {
...
};
In this case VisibleGameObject privately derives from Sprite. Then users of former cannot access any member of the latter (as if it it were a private member). In particular, Sprite's public and protected members are hidden to VisibleGameObject clients.
Had the inheritance been public, then all Sprite's public and protected members would be exposed by VisibleGameObject to its clients. With private inheritance we have a finer control of which methods should be exposed through using declarations. For instance, this exposes Sprite::changeImage:
class VisibleGameObject1: private Sprite, public GameObject {
public:
using Sprite::changeImage;
...
};
Forwarding methods
We can give to VisibleGameObject public methods that forward the call to m_sprite as show below.
class VisibleGameObject2: public GameObject {
public:
void changeImage() {
m_sprite.changeImage();
}
private:
Sprite m_sprite;
...
};
I believe this is the best design, especially as far as encapsulation is concerned. However, it might require a lot of typing in respect to other alternatives.
Structure dereference operator
Even plain old C provides types that exposes another type's interface as if it was its own: pointers.
Indeed, suppose that p is of type Sprite*. Then by using the structure dereference operator -> we can access members of Sprite (pointed by p) as shown below.
p->changeImage();
C++ allows us to endow classes with customised struct dereference operators (a feature well used by smart pointers). Our example becomes:
class VisibleGameObject3 : public GameObject {
public:
Sprite* operator ->() {
return &m_sprite;
}
private:
Sprite m_sprite;
...
};
and
VisibleGameObject v;
v->changeImage();
Although convenient, this method has many flaws:
As for public inheritance, this approach doesn't give a fine control over which Sprite public members should be exposed.
It works only for one member (that is, you cannot use the same trick to expose two members interfaces).
It messes up with the interface. Indeed, consider for instance that VisualGameObject has a method doSomething(). Then, to call this method on an object v one should do v.doSomething() whereas to call changeImage() one should uses v->changeImage(). This is confusing.
It makes VisibleGameInterface to look like a smart pointer. This is semantically wrong!
C++11 Wrapper Pattern
Finally, there's Sutter's C++11 Wrapper Pattern (watch his presentation, specifically the second slide of page 9):
class VisibleGameObject4 : public GameObject {
private:
Sprite m_sprite;
public:
template <typename F>
auto operator()(F f) -> decltype(f(m_sprite)) {
return f(m_sprite);
}
};
Clients use it this way:
VisibleGameObject4 v4;
v4( [](Sprite& s) { return s.changeImage(); } );
As we can see, compared to the forwarding methods approach this transfer the burden of typing from the class writter to the class clients.
It looks like you are trying to directly access Sprite's function without referencing it first. Try this:
man.m_sprite.changeImage() ;
Note that m_sprite and changeImage() should be public for you to do this. Otherwise use a public accessor function to manipulate private class members.
Building a GUI system and I have a few classes for different GUI components that derive from a base "GUIcontrol" class. What I want is to have just one function to return any type of component but be able to work with the functions specific to that component type (functions of the derived class). I noticed that the polymorphism approach is going to become a problem I have to declare all the derived functions in the base which is unnecessary for this, since I will never create an object just from the base class.
class GUIcontrol {
protected:
std::string _name;
// these two methods (along with name()) will be used by all types
virtual void position(/*parameters*/)
virtual void useImage(/*parameters*/)
// these should be only in derived types
virtual void setHotSpot(/*parameters*/);
virtual void setScrollButtons(/*parameters*/);
public:
std::string name();
/*etc*/
}
class GUIbutton : public GUIcontrol {
public:
void setHotSpot(/*parameters*/);
}
class GUIscrollBar : public GUIcontrol {
public:
void setScrollButtons(/*parameters*/);
}
GUIcontrol* GUIsystem::getControl(std::string name);
The problem with this is that if I want to add more functions unique to GUIbutton or GUIscrollBar, or any functions to other derived GUI classes, I also have to declare them virtual in the base class so the compiler doesn't complain about something like "setHotSpot" not being a member of the base class it returns.
The base class does have member functions that will apply to all the derived classes, such as telling the object where it should be positioned, what image it needs to use, what it should be called, etc. But I don't want to keep stuffing the base class with other functions that need to stay exclusive to certain derived classes.
As I keep adding more virtual functions I would end up with a huge blob object for the base class. Can I design this in a cleaner way? Note that I am still not sure if I want to use static_cast/dynamic_cast for getControl() to solve this but just want to know if there are any other ways around this to clean it up.
The base class should only contain methods for functionality common to all controls.
If you're going to use functionality that only makes sense for one type of control, you should be checking that the control is of the correct type anyway, and can then cast it to that type.
The base class is exclusively common functionality. If you want your method to behave differently for different controls, use dynamic_cast. If you want it to act the same for all controls, use a virtual method.
This is your problem:
What I want is to have just one
function to return any type of
component but be able to work with the
functions specific to that component
type (functions of the derived class).
What you want is to treat them the same but differently. Huh. I wonder how you're going to make that work. You need to decide if you want to treat them all the same, or if you want to treat them differently.
Type checking and then downcasting isn't the right way to do this. What you should be doing is placing generic methods onto your base class which perform the types of operations you want, and then overriding them in subclasses. For example, if you want the GUIControl to be able to draw itself, then put a doDraw() method on the base class, then override that in each subclass to do as is needed. If you instead put a getTitleBar(), getText() etc. methods on your subclass, then have the caller downcast and calls those specific methods depending on the type, your encapsulation is broken. If you have some common code that multiple subclasses need to do their drawing, then you factor this out either through another parent class, or through composition. Using dynamic_cast, or putting specific methods on the generic subclass, will likely make your code worse.
If I have this right: You want to be able to pass around base class objects but have a clean way to call specific derived class methods where the derived class implements those methods?
Sounds like the 'mixin' pattern might help:
struct Base
{
virtual ~Base() {}
};
struct Mixin
{
virtual ~Mixin() {}
virtual void mixedMethod() = 0;
};
struct Concrete : Base, Mixin
{
virtual void mixedMethod() { std::cout << "Mixing" << std:: endl; }
};
Base* create() { return new Concrete;}
bool mixIt(Base& b)
{
Mixin* m = dynamic_cast<Mixin*>(&b);
if (m)
m->mixedMethod();
return m;
}
void test ()
{
Base* b = create();
assert(mixIt(*b));
Base base;
assert(!mixIt(base));
}
[ Yes, real code never uses struct for polymorhic classes; just keeping it compact.]
The idea here is that the availability of a given method is encapsulated in the Mixin class, which is an pure abstract base class, possibly with only a single pure virtual function.
If you want "know" your base class object is of the derived type, you can call the mixin classes method. You can wrap the test and the call in a non-member function; this allows you to keep the base calss interface itself clean.
I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.