C++: Redefine one or the other operation in the child class - c++

In the following code:
class GraphicalCardDeck : public CardDeck, public GraphicalObject {
public:
virtual void draw () {
return CardDeck::draw();
}
virtual void paint () {
GraphicalObject::draw();
}
}
GraphicalCardDeck gcd;
gcd->draw(); // selects CardDeck draw
gcd->paint(); // selects GraphicalObject draw
When in the class CardDeck there is a function named draw, and in the class GraphicalObject there is a function named draw.
The book mentions a problem when we do:
GraphicalObject* g = new GraphicalCardDeck();
g->draw(); // opps, doing wrong method!
Why will it call the wrong method? It will not call the function draw in the class CardDeck as we define?
Thank you.

Yes, it will call the function draw in the CardDeck as we defined. But that might be surprising to someone not familiar with the internals of our class:
GraphicalObject* g = new GraphicalCardDeck();
g->draw(); // opps, doing wrong method!
Someone that wrote this might expect that GraphicalObject::draw() is called (or at least an overwritten version of that function that provides the same functionality). Since our overwritten function provides completely different functionality (that required by CardDeck), from the perspective of the one writing the above code the "wrong" function is called (aka. not the one he intended to call).
So it works like you expected, but when just looking at the interface and without knowledge of the internal implementation one might expect different behavior.

Related

How will this C++ code work?

Here's a bit of code:
======================
[Player.cpp]
======================
#include "TmTeam.h"
#include "TmPlayer.h"
#include "Player.h"
void Player::doTurn()
{
(...)
Tm_doPost();
(...)
}
===================
[Player.h]
===================
class Player
{
(...)
public:
(...)
virtual void Tm_doPost() = 0;
(...)
};
===================
[TmPlayer.cpp]
===================
#include "TmPlayer.h"
#include "TmTeam.h"
void TmPlayer::Tm_doPost()
{
(...)
}
===================
[TmPlayer.h]
===================
#include "Player.h"
class TmPlayer : public Player
{
public:
(...)
void Tm_doPost();
(...)
};
===================
[Team.cpp]
===================
#include "TmTeam.h"
#include "TmPlayer.h"
#include "Team.h"
void Team::doTurn()
{
(...)
Tm_doPost();
}
===================
[Team.h]
===================
class Team
{
(...)
public:
(...)
virtual void Tm_doPost() = 0;
(...)
};
===================
[TmTeam.cpp]
===================
#include "TmTeam.h"
#include "TmPlayer.h"
void TmTeam::Tm_doPost()
{
(...)
}
===================
[TmTeam.h]
===================
#include "Team.h"
class TmTeam : public Team
{
(...)
public:
(...)
void Tm_doPost();
(...)
};
I'm wondering which implementation of Tm_doPost() will execute in both the calls that are shown here... I presume that the one in Team.cpp will use the definition provided by TmTeam.cpp (please correct me if I'm wrong), but what about the call made in Player.cpp? Will it use the definition that's in TmPlayer.cpp, or will just return 0 like it says in Player.h? And in both Player.h and Team.h, what does the keyword virtual does there?
By the way I tried to be as accurate as possible with the includes on top of each block of code, in case it's relevant to the question...
I will try my best to answer your questions, so to be clear I quoted the part of your question that I'm answering.
Your Question 1: I'm wondering which implementation of Tm_doPost() will execute in both the calls that are shown here... I presume that the one in Team.cpp will use the definition provided by TmTeam.cpp (please correct me if I'm wrong),
I think your wording is making it misleading. You see, you can't make an instance of a "Team" object, because it does not implement the virtual function "Tm_doPost()". If you look at the Team.cpp file, that it only implements Team::doTurn().
However, the class "Team"'s subclass "TmTeam" does implement the virtual function "Tm_doPost()", so it can be instantiated.
You could have a list of "Team"s, which contains many "TmTeam" instances. In fact, any superclass can be used as a overarching class name for the subclasses. It's called "polymorphism."
example:
List<Team> myList = new List<Team>();
myList.push_back(new TmTeam());
myList.push_back(new TmTeam());
myList.push_back(new TmTeam2()); // <--- if you have a class like this: " class TmTeam2 : Team"
//Notice there's mixed items on a list of "Team"s, because each item shares the same parent class.
Now, if we did this code:
//pseudocode, iterating through each item in myList, giving it the variable name "x"
for (each Team, x, in myList)
{
x.Tm_doPost();
}
Which implementation of Tm_doPost() will be executed? Will it be the one in TmTeam.cpp? Not necessarily. The TmTeam objects in myList will use that function, but the TmTeam2 object will use its definition. You can have many subclasses, and each subclass must implement the virtual functions for it to be able to be instantiated. Whenever it is in a list of Team objects, the compiler wonders: 'I need to call "Tm_doPost()" but I'm not sure which subclass this is. Is it a TmTeam or a TmTeam2?' However, it doesn't need to wonder, because C++ is designed that it finds out what the object really is, whether it's TmTeam or TmTeam2. Then, it calls the function on the TmTeam object, which naturally uses the definition of that function within its own class definitions. TmTeam2 will use its definition. Just like normal C++ behavior is expected to work.
So, since in Team.cpp, "Tm_doPost()" is virtual, it will have to find out what is the actual (instantiatable) object is and then call its implementation of "Tm_doPost()."
Your Question 2: but what about the call made in Player.cpp? Will it use the definition that's in TmPlayer.cpp,
It depends. Since Player is not able to be an instantiated object, then when calls are made on it (as if there is a list of Players, like the example above), it must find out what the object REALLY is - which will be some subclass of Player. If the subclass happens to be TmPlayer, then it will call TmPlayer class's implementation of Tm_doPost():
void TmPlayer::Tm_doPost()
However, if it happens to be another (theoretical) subclass of Player, such as "TmPlayer2", then it will call its implementation of Tm_doPost():
void TmPlayer2::Tm_doPost()
You see, the method that is called really depends on what the actual instance class is.
Your Question 3: or will just return 0 like it says in Player.h?
In Player.h, the line I think you are referring to:
virtual void Tm_doPost() = 0;
does not mean that it will return anything. It is just some syntax that tells the compiler that this function will not be implemented in this class - only the subclasses will be allowed to implement it.
The syntax could have been
virtual void Tm_doPost() ~ $;
and get the job done still - there's not special meaning to it. I guess a nice way to look at it, is to say that this function's implementations in this class equals 0 (or, none).
Your Question 4: And in both Player.h and Team.h, what does the keyword virtual does there?
It makes it so whenever that function is called, it will look up what the instance object's real function is, and execute that.
It also makes it so any subclasses can choose to override the function by declaring another function with the same name. But, they can also choose not to override it, and then the parent class's default function can be used instead. (This is if there is no "=0;" syntax - if it's not a pure virtual function.)
If it is a pure virtual function and you do not override it in a subclass, then that subclass cannot be instantiated either, and its subclass can only be instantiated if it overrides it.
Final comments & recommendations:
This is my best understanding at the moment of virtual functions, but I highly recommend the whole Chapter 12 of this site: http://www.learncpp.com/cpp-tutorial/122-virtual-functions/ It is where I learned what I know.
I honestly found that the best way for me to learn virtual functions was to follow online tutorials while also doing little practice-program experiments, making a bunch of classes, some which inherited from others, and had different functions, and then I got to find out which function got executed, depending on what it printed to the terminal.
Then of course, using stack overflow along the way helps for bug-related issues.
The functions declared as
virtual void Tm_doPost() = 0;
don't return 0. They are purely virtual, and define the interface of the class. Both subclasses you're asking about will call their ancestors methods and the Player::doTurn() method will call current object's Tm_doPost() method.
Member functions declared with virtual keyword are called using object's virtual methods table. So when an object of a class is instantiated all virtual methods are called by referencing the addresses stored in the table. That's why the superclass Player doesn't need to know the implementation of the Tm_doPost method.
When you call a function like this,
void Player::doTurn()
{
//...
Tm_doPost();
//...
}
i.e. within the member function of the class Player, the compiler should look for the function in that class, which in this case happens to be a pure virtual function without definition, so you can't call it. This name lookup business hardly has anything to do with files.
I don't know what your code does, but since you have a Team, a Player and a TeampPlayer class, I assume you're trying to aggregate players in a team and achieve polymorphism with the call to tm_doPost()? This is the way to do it
#include <iostream>
struct player{
virtual void foo(void){std::cout<<"player::foo";}
};
struct teamPlayer: public player{
virtual void foo(void){std::cout<<"teamPlayer::foo";}
};
then when you'll have dynamic binding with the function foo;
int main(int argc, char** argv){
teamPlayer t;
player* p = &t;
p->foo(); //outputs "teamPlayer::foo"
return 0;
}

std::bind inside of a class, general concept of an event system

I'm working on a library that's based upon a simple event-system.
For work with GUI elements ("controls"), these are needed a lot. For example, the Window class has got a bunch of events, like "onMouseMove", "onKeyPress", "onKeyRelease", .. However, the basic class for controls is the Control class. It has a virtual function draw (which obviously draws the control) and a virtual function connect which connects the control's and the main window's events (works similar to the Qt Signal-Slot-Concept).
But since the Event class takes an std::function<...> pointer as subject (=> Slot), I cannot simply connect a member function of a derived control class with an event of the window. As a workaround, I'm doing the following thing:
class A : public Control {
friend class Window;
public:
A(){
this->eventHandler = [this] () -> void {
if ( someCondition ) this->onSomeCondition.notify();
};
}
Event<> onSomeCondition;
protected:
std::function<void()> eventHandler;
void connect(Window *window){
window->onSomeHigherEvent.attach(&this->eventHandler);
}
void draw(...) const{
drawSome(...);
}
};
What this basically does is that it assigns a lambda function to the std::function<...> in the constructor and attaches that std::function<...> to the chosen event.
There is a major problem though: What happens if I instantiate a few more objects of that class? If I had the event handlers specified in the class, as a normal function like so:
void eventHandler() {
if ( someCondition ) this->onSomeCondition.notify();
}
And could assign that function to the std::function<...> using std::bind, which does not work for some reason, at least as long as I'm using the following call:
std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.
Anyways, the lambda-function-workaround seems to be less time efficient since it's not really built into the class. Is there a more efficient way to solve this problem? Maybe not by solving the lambda-function problem in particular but by changing the concept?
I'm not sure what your asking, since I can't find the question, but ...
std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.
This creates a callable object that has one unbound parameter, i.e. it expects to be called with one argument, which is not compatible with std::function<void()> because that is a function that expects to be called with no arguments. It's also not compatible with the eventHandler member function you show, because that too takes no arguments.
Maybe you just want to use std::bind(&A::eventHandler, this);

Recursive Strategy Pattern

I am designing some classes for my project in C++ at the moment but I got a problem.
I want to create a camera class which holds all the needed values (e.g. transformation matrices) but the function which renders the camera should be exchangeable. This sounds like a usual case for the strategy pattern. Thus I created an interface which defines the render-function and gave the the camera class a pointer to this interface.
The problem is that the render function needs access to all the data in the camera class and therefore I gave this function a pointer to the camera class as a parameter. It looks like this:
#include "ICameraRender.h"
class Camera{
private:
ICameraRender* _cameraRender;
public:
Camera();
Camera(ICameraRender& cameraRender);
~Camera();
void renderCamera(){ _cameraRender->render(this); }
void setCameraRender(ICameraRender& cameraRender);
/..../
};
class ICameraRender{
public:
virtual ~ICameraRender(){
}
//Override me
virtual void render(Camera* camera) = 0;
};
This doesn't seem to be an elegant solution due to the liability to an infity loop (calling camera->renderCamera() in the render-function in ICameraRender). Is there a better solution to this problem?
Regards
EDIT:
I came up with another solution. Since the function which operates on the camera's data, only needs access to the data I thought I could split up the camera class itself. A class called Camera and CameraModel. The last one holds all the needed data and the first one does operations on it.
Therefore I just have to pass a pointer to CameraModel to my function:
class CameraModel{
private:
/...data.../
public:
/...setter and getter.../
};
class Camera{
private:
CameraModel* _cameraModel;
ICameraRender* _cameraRender;
public:
Camera();
Camera(ICameraRender& cameraRender);
~Camera();
void renderCamera(){ _cameraRender->render(_cameraModel); }
void setCameraRender(ICameraRender& cameraRender);
/..../
};
class ICameraRender{
public:
virtual ~ICameraRender(){
}
//Override me
virtual void render(CameraModel* cameraModel) = 0;
};
Now the render-function (which only calculates new values for the camera according to user input) does no longer have access to the renderCamera-function.
What do you think about this solution?
Regards Stan
You're right, it does seem like a bad design. :)
I don't see why a camera render needs access to a camera. I'm sure you can pass something else as parameter. The render doesn't need access to all the camera members, so you can just pass the ones it needs (and, if there's a lot of them, wrap them in a structure CameraConfig or something like that).
If the different renders need different parameters, you can make a separate hierarchy with ICameraConfig.
This is probably a great time to use Policy-based design to implement the strategy pattern, especially since you're using C++ and you're probably targeting a compiler older than 2002. (Since C++'s templating mechanism is so awesome, we can get the strategy pattern for free this way!)
First: Make your class accept the strategy/policy class (in this case, your ICameraRenderer) at a template parameter. Then, specify that you are using a certain method from that template parameter. Make calls to that method in the camera class...
Then implement your strategies as a plain old class with a render() method!
This will look something like this:
class Camera<RenderStrategy>{
using RenderStrategy::render;
/// bla bla bla
public:
void renderCamera(){ render(cameraModel); }
};
class SpiffyRender{
public:
void render(CameraModel orWhateverTheParameterIs){ // some implementation goes somewhere }
};
Whenever you want to make a camera that uses one of those policy/strategies:
// the syntax will be a bit different, my C++ chops are rusty;
// in general: you'll construct a camera object, passing in the strategy to the template parameter
auto SpiffyCamera = new Camera<SpiffyRender>();
(Since your renderer strategy doesn't have any state, that makes this approach even more favorable)
If you are changing your renderer all the time, then this pattern / approach becomes less favorable... but if you have a camera that always renders the same way, this is a slightly nicer approach. If your renderer has state, you can still use this method; but you'll want a reference to the instance inside the class, and you won't use the Using:: statement. (In general, with this, you write less boilerplate, don't need to make any assignments or allocations at runtime, and the compiler works for you)
For more about this,see: http://en.wikipedia.org/wiki/Policy-based_design
Or read Modern C++ Design... it's a great read, anyways! http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315
As an unrelated aside: You may want to look into some of the goodness that C++x11 gives you. It'll really clean up your code and make it safer. (Especially the shared/unique/etc ptr classes.)

redefining or adding a classes member function dynamically/ during execution

Hey i'm trying to make a very simple GUI using SFML, and i want to be able to attach a function to my Button class in the constructor, as so the user can define what happens when the button is pressed.
I've worked a little before with GLUT and noticed these declerations:
glutReshapeFunc(Resize);
glutDisplayFunc(Draw);
Which apparently define what function should be called when the window is resized or displayed. I want something exactly like this for my button so upon construction you can define what function should be called. I want to be able to pass a function name just like glut, not having define a new class wich overides a virtual functin.
I also doubt it's possible however to pass parameters for these
called functions, as you never know what or how many there would be.
Am i right?
So anyway..... How do i accomplish this or something like it?? Thanks!
You can store a callback using e.g. std::function (for C++0x; boost::function is also available and has a similar interface).
#include <functional>
class Button {
public:
template<typename T>
explicit
Button(T const& t): callback(t) {}
void
press()
{
callback();
}
private:
std::function<void()> callback;
};
// example use with a lambda
Button b([] { do_stuff(); });
b.press(); // will call do_stuff
In C++ it's better to use virtual function approach to address such kind of problems. That's more maintainable at long run.
You can choose to redesign a little bit to your code, where you can have a common handle to various subclasses. Now based on subclass chosen you can call a particular function. For example:
class Shape
{
public:
virtual void Resize () = 0;
virtual void Draw () = 0;
};
class Triangle : public Shape
{
public:
// implement above to functions
};
class Square : public Shape
{
public:
// implement above to functions
};
Now, just pass the handle of Shape* wherever you want and call the above abstract methods;
void foo(Shape *p)
{
p->Resize();
}
(Rewrote everything), I had misread the question.
You seem to be wanting to pass plain old function pointers around to other functions. All you need to do is just pass the name of the function you want, but do so inside an if (or something like that) so the function passed is actualy what you want:
if(i am feeling lucky today){
glutDisplayFunc(DrawMyLuckyShape);
}else{
glutDisplayFunc(DrawAFoo);
}
The bad news is that since C is a nasty language you can't set up to pass extra parameters to your functions (ie, use closures). Therefore, you need to rely on a) the functions being passed some parameter quen being called or b) the functions looking at some global state.

Matching an overloaded function to its polymorphic argument

Okay, the title is a mouthful and I think that's probably why it has been tough to find an answer through google or this site. It might just be that I don't know how to express the problem correctly but here goes:
I have a series of methods in a SimpleOpenGLRenderer class that all take a single argument that extends the Model class. So the idea is that depending on the type of model, the renderer will invoke the correct method that knows how to render it. Here is a simplified executable example based on the problem:
#include <stdio.h>
class Model {};
class Cube : public Model {};
class Sphere : public Model {};
class Renderer
{
public:
virtual void renderModel(const Model& model) = 0;
};
class SimpleOpenGLRenderer
{
public:
void renderModel(const Cube& model)
{
printf("Render the cube.\n");
}
void renderModel(const Model& model)
{
printf("Throw an exception, my renderer does not support the model type you have provided.\n");
}
void renderModel(const Sphere& model)
{
printf("Render the sphere.\n");
}
};
int
main(int argc, char** argv)
{
Cube cube;
Model& model = cube;
SimpleOpenGLRenderer renderer;
renderer.renderModel(cube);
renderer.renderModel(model);
}
The output from the example is:
Render the cube.
Throw an exception, my renderer does not support the model type you have provided.
It may seem obvious to a more seasoned C++ developer that this does not work as planned but it just doesn't make sense to me. At runtime I will not know the exact type of the Model passed to the renderer (hence the attempted overloading to resolve it). Coming from a Java background, I have used this technique before and in Java the method called will be that which best matches the runtime type of the argument. In C++ it seems to match to the compile-time type of the reference, even if that reference may end up being to a subclass that - to my mind - better matches another function.
Up until now I had taken this runtime type matching for granted. Does it simply not exist in C++ or am I going about this the wrong way? Should I be doing something differently in C++ to achieve it?
Thanks,
Gary.
Overloads in C++ are resolved at compile time, based on the static type of the argument.
There's a technique known as "double-dispatch" that might be of use:
class Model {
virtual void dispatchRender(Renderer &r) const = 0;
};
class Cube : public Model {
virtual void dispatchRender(Renderer &r) const {
r.renderModel(*this); // type of "this" is const Cube*
};
int main() {
Cube cube;
Model &model = cube;
SimpleOpenGLRenderer renderer;
cube.dispatchRender(renderer);
}
Note that the Renderer base class needs to contain all the overloads that SimpleOpenGLRenderer currently does. If you want it to be specific to SimpleOpenGLRenderer what overloads exist then you could put a Simple-specific dispatch function in Model, or you could ignore this technique and instead use dynamic_cast repeatedly in SimpleOpenGLRenderer::renderModel to test the type.
In your code, the function overloads are resolved based on the static type of the argument.
What you need probably is double-dispatch mechanism which is very close to Visitor pattern. Read these:
Double Dispatch
Visitor Pattern
For "runtime overloading" based on the dynamic type it is possible to use visitor pattern.
Your code is a good candidate of runtime type matching, if you use it. Here you are receiving Cube into Model& and passing the same simply to the renderModel(). Till now you haven't given chance to the compiler to use the runtime type. But rather relying on the static type of the object.
In 2 ways you could have used the runtime type checking. One is using dynamic_cast<> and other one is providing the interface method in Model. i.e.
class Model {
virtual void print () { printf("throw..."); } // provide an interface method
};
class Cube : public Model {
virtual void print () { print("Render cube\n"; } // implement it
};
class Sphere : public Model {
virtual void print () { print("Render sphere\n"; } // implement it
};
class SimpleOpenGLRenderer
{
public:
void renderModel(const Model& model)
{
model.print();
}
};
In C++ the resolution of which overload to call, is done at compile time.
To make the effective implementation depend on the polymorphic argument type, you need to consult that argument, i.e., call a virtual method on the argument.
I think the cleanest way to do that here is what's called the visitor pattern. Your SimpleOpenGLRenderer can call a method model.renderOn( *this ). Then Model::renderOn is either a set of overloads, one for each possible type of renderer, or it is a single virtual method that uses dynamic_cast to discover the type of renderer. In any way, it then calls back on the renderer, but now that call knows what type of renderer it is and what type itself is, and can also call a very specific rendering method, like, SimpleOpenGLRenderer::renderCube.
Cheers,
The other solutions here will do exactly what you want. But in my opinion at the cost of complexity. If your problem is exactly as described, I would suggest to change the architecture of your solution instead. Aren't the renderer trying to do the job of the model? What I see is a kind a overload generated switch sentence.
How about making the models rendering themself, perhaps by using some class offering more primitive drawing methods:
class Cube : public Model {
render(RenderTool& tool) {
tool.renderCube(); //or even more low level
}
};
class SimpleOpenGLRenderer {
public:
RenderModel(Model& model) {
model.render(renderTool);
}
private:
SomeOpenGLRenderingTool renderTool;
};