I am working on an application with a GUI using wxWidgets. I got an object used as a "model": its data has to be used to draw the ui and the ui should modify it. Let's call this class Model.
The structure of the applications looks like this:
A wxApp-derived object, that possesses:
a wxFrame-derived object, that possesses a
wxGLCanvas-derived object.
another wxFrame-derived object.
For the Model class,
I could use a singleton that
would make things very simple: I
could just use model.getThatData()
or model.setThatData() anywhere.
However, I can't disagree when people
say that it's a global variable with
a fancy dress.
I could also use dependency
injection (or is it something
else): I instanciate Model in the
wxApp object, and then I pass a
reference to the instance model in
the constructors of both wxFrame-derived classes,
same thing with wxGLCanvas
constructor, and I store the
reference as an attribute of the
needed classes.
However, this doesn't seem either a
very good solution. Suppose the
first wxFrame object doesn't need
to use model. We will nontheless
have to pass a reference to model
in its constructor to be able to
pass it to the wxGLCanvas-derived
object. So that design could lead to
many (?) unnecessary passings.
?
What do you think ? I have been asking myself this question for a long time...
However, this doesn't seem either a very good solution. Suppose the first wxFrame object doesn't need to use model. We will nontheless have to pass a reference to model in its constructor to be able to pass it to the wxGLCanvas-derived object. So that design could lead to many (?) unnecessary passings.
Passing pointers around is peanuts compared to the nightmares of untangling the dependencies between classes/objects, hidden in the implementation (== singletons).
The #2 is the way I do it. The goal is to be able just by looking at the class declaration to have an idea about the class prerequisites. Ideally, if in the context I have everything what c'tor/init method needs, I should be able to instantiate and use the object. That way the life-cycle also becomes clear: the prerequisites may not be released until the object is released.
Does the frame dependent on a specific canvas class? Or the canvas object interchangeable?
If the latter is the case, then the constructor for the frame should be parameterized by a reference to a canvas object. This way, the application will take care of instantiating the model, creating the canvas using said model, and passing the canvas to the frame. The frame will no more be dependent on the model directly.
If the frame is dependent on a specific canvas class (that is, the frame instantiates its own canvas, and knows what type of canvas it wants). Then if the canvas' constructor is dependent on the Model object, by proxy your frame is also dependent on the model. So #2 is correct.
Put it into a simple MVC model. (Recall that C interacts with M and V, and M and V do not interact with each other.)
Your model is (obviously) the "M" in MVC. Your widgets are the "V" in MVC.
See the problem here? You're trying to give the "M" to the "V"; you're missing the "C" to delegate everything. Your "C" may be your wxApp (it depends on how you want to design things).
In other words, the controller should give the data the view needs from the model to the view; the view shouldn't grab its own data directly from the model.
(Therefore, both of your proposals are, in my opinion, poor options in an MVC application.)
Related
I am designing a game engine in c++. I am currently working on categorizing the different entities in the game. My base class is SpriteObject that two classes MovableObject and FixedObject inherit from. Now if i for example create an instance of a MovableObject and want to add it to a Vector of Sprite and a Vector of MovableObject i just do:
Vector<Sprite*> sprites;
Vector<MovableObject*> movableObjects;
MovableObject* movingObject = new MovableObject();
sprites.push_back(movingObject);
movableObjects.push_back(movingObject);
But as the different categories and entities grow the code will get large (and it would get tiresome to add every entity to every vector that it belongs to). How do i automatically add an object to the vector that it belongs to when it is created?
EDIT 1: I think i just came up with a solution, what if i just make a global static class Entities that holds all the vector of entities in the scene. Every entity could have access to this class and when a entity is created it just adds a pointer version of itself to the corresponding vector(s) in that global class.
EDIT 2: But i forgot that my solution requires me to still manually add every entity to its matching vector. I just split the work among the different entities.
This is a nice problem.
I think that I would implement it like this: There will be an addToVector() method in Sprite class, and each derived class will override it to add itself to the corresponding vector.
I would suggest a different approach. But before I start I would like to note one thing with your current design.
I would hide the creation of those objects behind a facade. Call it a scene or whatever. Using new manually is bad from a couple of perspectives. First of all if you decide you want to change the scheme on how you allocate/construct your objects you have to change it everywhere in the code. If you have a lets say a factory like Scene you just change the implementation and the calls to scene->CreateObject<Sprite>() will remain the same everywhere else. This might get important once you start adding stuff like custom memory allocation schemes, object pools etc and at some point you will if you will start to grow your engine. Even if this is just an excercise and a for fun project we all want to do this like its actually done, right ;) ?
Now going back to the core - dont abuse inheritance.
MovableObject is not a Sprite. Static Object is not a sprite either. They are that, movable and static elements.
A sprite can be movable or static, so it has a behavior of a dynamic or static element.
Use composition instead. Make a Sprite accepting behavior, or better a list of behaviors. In fact the Sprite itself is just a behavior on a Game object too, it just controls the way it is presented to the user.
What if you had an object that can be attached multiple behaviors like the fact it is a dynamic one, it has a sprite presence on the scene and even more is a sound emitter!
If you add those behaviors to the object you have to create them first. They can, when constructed, decide to which list they should subscribe to.
This is all metaphors for actually a well known system, that is proven to work well and is actually used in most game engines nowadays. Its a Entity Component System.
You object with behaviors are Entities, Components are those Behaviors and each of them is controlled by one system that knows the component and knows how to update/handle them.
Objects in the scene are merely a set of components attached to them that act upon them.
I have a question on where to create, own and destroy data.
The data itself are large tables of numbers, either randomly generated or read from the hard drive. This data is then subject to analysis, and depending on what exactly is analyzed, I have made a few wrapper like structures, which encapsulated the desired functionality. Since the wrapper can be switched in later stages, I decided against creating/reading the data inside the wrapper constructors, and just handle them in the "main" function. The wrappers then only see pointers of the data.
First of, is this common/ a good idea, or should a wrapper always own its own copy of the data it wraps around?
Well, next I made a "menu" class to better navigate through data creation/analysis choices etc, and the easiest would be to make the data part of the menu class. This doesn't feel good though, so where should I put it? Should it stay in the main class?
I hope this is understandable. If not, I can try to give a better outline of what is happening.
Thank you for reading.
You could create a data class, and wrap other classes around it. An object of the data class probably should be global or defined inside main. OTher than that - your idea seems good. WIth a data class defined, you could also pass a pointer/reference to the menu, so you wouldn't have the problem with that. Note that a menu can also be a wrapper if you wish.
It's generally a better idea to keep the details of data in a specific wrapper class (I think you mean derived class?). Your wrapper classes should be derived from an interface or abstract type. You can construct wrapper-class factories in main(), and pass the factories around to constructors (constructors of the classes that are instantiated in main()). Later when the data-specific wrapper needs to be switched on or created, invoke the factory method. The factories can own the pointers, by which I mean they call new() and delete(). Try looking up SOLID principles and see how they guide you.
Sorry for the dumb question, but I'm working with Qt and C++ for the first time, and working through the tutorial and some samples.
One thing that was mentioned was that Qt stuff doesn't need to be explicitly deleted. So, main question, does this also apply to collections of Qt stuff? Like say I want a dynamic number of MyWidgets, so I keep a vector or whatever of them. Are they still taken care of for me?
As a side question, what is going on to make it so I don't have to worry about destructors?
The Qt memory management model is based upon a parent-child relationship. Qt classes take an optional parent as a parameter of their constructor. The new instance registers with this parent such that it is deleted when the parent is deleted. If you are using a Qt collection (e.g. QList), I believe you can set the list as the parent of its entries. If you're using an std::vector or other collection type, you will not get "automatic" memory management.
The Qt model makes a lot of sense in a UI hierarchy where it matches one-to-one with the UI hierarchy. In other cases, it doesn't always map as cleanly and you need to evaluate whether using the Qt system makes sense for the particular situation. The normal C++ tools still work: you can use std::tr1::shared_ptr or any of the other smart pointer classes to help you manage object lifetime. Qt also includes QPointer, a guarded pointer, and the QSharedPointer/QWeakPointer pair that implement a reference-couting smart pointer and weak-reference pair.
Qt has an interesting object model for sure. When I first started it made me uneasy that there were so many new Foo calls and no deletes.
http://qt.nokia.com/doc/4.6/object.html Is a good place to start reading up on the object model.
Things of interest:
QObject subclasses have their assignment and copy-ctor methods disabled. The chain of object child-parents is maintained internally by QObject.
Generally when instantiating a QObject subclass (if you don't plan on managing its pointer yourself) you will provide another QObject pointer as the parent. This 'parent' then takes over the management of the child you just made. You can call setParent() on a QObject to change who "owns" it. There are very few methods in Qt that will change the parent of an object, and they all explicitly state that they do in the docs.
So to answer your specific question: it depends on how you made all of your MyWidget instances.
If you made each one with a parent, then no you don't have to delete them. The parent will delete them when it gets deleted.
If you're keeping a QList<MyWidget*> collection of them, and you didn't give them a parent, then you should delete them yourself.
I need suggestions on how to solve the type of problems described below. I'm fairly new at C++ and OO-design.
I've learnt:
Pointers shall be avoided when ever they can be replaced by references.
Objects shall have no knowledge of objects that they don't need to know about.
But when creating objects having references to other objects we must pass these references as input arguments to the constructor. Thus we need to know about objects we should not not know anything about.
But look at the following example:
Suppose I have a object "Menu" that needs to have it's own timer object "Timer". I'd like to implement this association as a reference.
The object MenuHandler aggregates a lot of Menu objects but shall not have any knowledge about Timer objects. But when the MenuHandler creates a Menu object it must pass a Timer reference argument to the constructor. Thus, ****MenuHandler** must know about **Timer****.
Any suggestions on how to treat these kind of problems?
I'd hesitate to bless your choice of words when it comes to the two numbered points. They're a sign you're on the right way learning C++, but they might be misleading to other novices. When I take a look at your concrete examples, this becomes more obvious.
A MenuHandler should not create menus. The content of menus is determined by by the application, so the application object (or the Controller part, if you've implemented Model-View-Controller) should create menus. The MenuHander merely takes ownership of menus created elsewhere.
Also, it may make sense to give each menu its own timer. That means the relation can be described as "Has a"; the menu has a timer. The relationship usually implmented by references can be described as "Knows a" (the inheritance relationship is usally called "Is a"). If each Menu object has a Timer, it can be a member, and initialized by the Menu constructor(s). The Timer object internally may obtain a reference to the system clock in its constructor, but that's not your concern.
Why not simply make the Timer object a member (by value) of the Menu class?
I find that I produce better (more maintainable, faster, etc) code and that I'm more productive using references in C++ than I would be solving the same problem with pointers... I think the traditional answer to your example would be to have a factory object that creates menus. In this way, the MenuHandler doesn't need to know about the Timer class.
The MenuHandler creates a Timer object, passes it into the Menu constructor, and forgets about it. That seems entirely reasonable.
If the MenuHandler unnecessarily kept a reference to the Timer, that would be against the advice point #2.
In a more general case where you need to provide a class to another class in order to do some kind of callback, you avoid mutual dependency (both know each other) by using an interface.
Class A derives from the interface. Class B accepts the interface as paramater in the constructor and calls the virtual function from that interface when needed.
Also check the observer design pattern.
For #1 Be very careful with the lifetime of your objects. References are no that suitable to handle dynamic graph of objets ( like your menu, menuhandler, timer, etc... ). What if you want to change the timer object later ?
It's not a good idea to have references as members in a class if the lifetime of referenced objects is not really known.
Avoiding pointer does not mean using references everywhere, you should have a look at smart pointers which will be more suitable for what you want to do.
My project involves Qt plus and unnamed 3rd party physics simulation library. The way the physics library works is that physical bodies cannot create themsleves; the "world" must instantiate them so that they can be added to the world immediately.
My project creates a wrapper around these physical bodies to add some extra functionality, but because it stores these physical bodies it can't be instantiated either. The first question is, does it make more sense to allow these bodies to stand on their own? The part that I find awkward is that I have to pass a reference to the world to the object so that it can be created, when, to me, it makes more sense to pass the object to the world.
To fix this, I can delay the creation of the 3rd party body until it is added to my world wrapper. But that means my world wrapper becomes in charge of initializing the body correctly. It also means that I can't really access any of the properties of the object until it's added to the world anyway, because they all rely on the 3rd party body being initialized... unless I duplicate all that data and then pass it off to the library when it's added.
Is it worth the effort, or should I just continue to pass a pointer to my world wrapper so that my body wrapper can be created?
I mention Qt, because the way the Qt graphics framework works is that you can create QGraphicsItems whenever you want, and they'll stand on their own, but they just won't be visible until you add them to the scene. The analogy here is that GraphicsItem == Body, and Scene == World.
To be truely effective, a facade pattern (your wrapper) has to hide the underlying details of the implementation from the user of the facade. This does mean using data transfer objects to hold the data. Facades can be cumbersome to implement but they give you the ability to change out the underlying implementation without affecting the end user.
sudo code:
Rock rock = new Rock(100); //simple data container for now.
PhysicsFacade f = new PhysicsFacade(); //internally creates world.
f.DoSomething(rock); //internally rock's data used by world to create an equivalent object which is attached to the rock data container for future use.
all my getters and setters basically need to check "has the body been initialized yet?"
If you're using Qt I suppose you're using C++.
I don't know Qt and I don't know why you want to change the existing mechanism, but anyway: one thing you can do in C++, that may be useful to you, is overload the -> operator to access your objects. When someone invokes the -> operator, the operator can also create the object just-in-time if it hasn't already beein instantiated, something like:
World& getWorld();
class Body;
class MyWrapper
{
Body* m_body;
public:
MyWrapper() : m_body(0) {}
Body* operator->()
{
if (!m_body)
{
m_body = new Body(getWorld());
}
return m_body;
}
... etc ...
};
Edit
What do you mean, "change the existing mechanism"? The one that the physics library has laid out? I think I mentioned my reasons.
Yes.
With your solution... what does getWorld() do? Is that a global function? If world is floating around in global space, then there isn't really a problem, I can just instantiate the body at the same time MyWrapper is instantiated.
Yes it returns a reference to the World, which is what you need to create a body in the physics library. It's an example, I don't know where you're getting your World reference from, nor when.
But what if the world still doesn't exist at the point that the -> operator is used? I'm not really sure this solves anything. Not to mention that one way or another, you're still passing the world to the body
Maybe getWorld will throw an exception if it's called too early. Anyway, what this was supposed to buy you was:
The ability to create your MyWrapper instances without a World reference and perhaps before the world is created.
The ability to create a Body instance just-in-time when a client tryied to access any of the Body's propeties or methods
The -> operator is what clients would using to get at the physics body which you're wrapping: like a "smart pointer".
It might be easier to understand and/or to suggest solutions for your problem if you'd illustrate your problem with some pseudocode.
Not to mention that one way or another, you're still passing the world to the body
You said that was a requirement of the underlying library. When you said, "Should I attempt to fix", I thought you meant "Shall I implement a different API in my wrapper, and hide the existing API within the my private implementation?" It didn't occur to me that you might try to change (not just wrap) the existing implementation.
Before I share my answer, let me rename a few things. "Object" is the thing that holds the "physics body". "World" is the thing that holds the "physics world". Again, only the "physics world" can create the "physics body" (its constructor is private).
Here's what I've done. The Object simply holds a pointer to the physics body. That way you can create Object whenever you want, and play with all it's data without even needing a world... you just can't touch the properties directly related to physics body (I'm going to ASSERT this).
The World finishes instantiating the Object (ie the physics body) as soon as it's added to the World. This perhaps breaks a tiny bit of OOP because the world has to manipulate a few of the Objects varibales to do so (I've made it a friend) but I think it's the least of the evils.