I read one of the book which deals with the issues of member function binding in c++.
and it's giving the next example:
void Window::oops() { printf("Window oops\n"); }
void TextWindow::oops() {
printf("TextWindow oops %d\n", cursorLocation);
Window win;
Window *winPtr;
TextWindow *txtWinPrt = new TextWindow;
win = *txtWinPrt;
winPtr = txtWinPtr;
win.oops(); // executes Window version
winPtr->oops(); // executes TextWindow or Window version;
I didn't understand why win.oops would executes window version? win is defined as Textwindow.
Thank you for your help.
This is caused by slicing. If you assign to an object of the super-class, the information from the subclass is lost. The problem is this statement:
win = *txtWinPrt;
Since you assign an object of a subclass (TextWindow) to an object of the super-class (Window), all the information of TextWindow that is not in Window is sliced away.
Window win
is an object of Window class. It should be pointer or reference to call derived class method with base class instance.
Two things are needed for dynamic polymorphism using object orientation (which is what you are asking for).
Window and Textwindow need to implement the "is-a" relationship. (so, class TextWindow : public Window {});
A virtual function is needed in a base-clase in order to get runtime polymorphism, generally a destructor if you cannot find a virtual function naturally. A virtual function causes the compiler to put down a v-table.
Without these two things, the compiler will not put a v-table down at callsites. The v-tables enables runtime polymorphism as function calls are indirected through it.
Alternatively you could resort to c-style function pointers, or something like boost::bind. But this defeats OO programming. I personally use a v-table very rarely.
Related
I have a player class that uses my DirectX Graphics class to create surfaces and draw sprites.
I am passing the graphics class as a pointer to the player class methodlike this:
**game.cpp**
m_pPlayer->Init(Graphics* graphics);
Inside the player class my Init method passes the pointer to another pointer method. Is there any benefit to creating another graphics pointer in the player class and copying the pointer argument instead?
So this:
**player.cpp**
m_pSurface->Init(graphics, m_width, m_height);
vs this:
**player.cpp**
m_pGraphics = graphics;
m_pSurface->Init(m_pGraphics, m_width, m_height);
I know that having a m_pGraphics pointer allows me to reuse the pointer again in the same class, such as my drawing method but I call the method in the player class anyway so can't I just keep passing the pointer over and over again?
This is just a matter of style and is unlikely to have any effect on performance. Copying pointers is very cheap and I would leave it to the compiler to optimize.
If player uses the Graphics object a great deal it would be reasonable to store a pointer in a member variable instead of passing it in all the time. It may make the member function signatures on player shorter which is good.
You do need to be sure that the member pointer to the Graphics object remains valid whenever it is used. Is it still the correct Graphics object and is it still alive? If you pass the pointer every time you might not have this complication.
I wrote this simple const class method:
void CTest::MSGTest() const
{
MessageBox(_T("This is a simple test"));
}
This method has an error:
The object has type qualifiers that are not compatible with the member function CTest::MessageBoxW
I know this is because i use the const. A method can be a const method if no member variables are modify while the execution. I would like to know which variables the MessageBox modify and how the modification manifests.
I think it is the handler m_hWnd, but I don't know.
The problem isn't that neither your function nor MessageBox modify any members variables - they don't and that's easy to see.
The problem is that MessageBox is not marked as const and so you have a const member function (yours) calling non const one (MessageBox). This isn't allowed and that's the issue.
So why isn't it marked const? I doubt you will ever get a definitive answer to that question if one reason really exists.
Personally, I suspect it's a combination of factors that caused it to not be const originally and now it is what it is.
One potential reason is that a lot of internal MFC bits and pieces involve the manipulation and adjustment of maps - for example maps which associate windows HWND objects to MFC CWnd objects.
It's possible that they had to relax the use of const to account for calls to non const functions deep down the call chain in places that users never see.
So why not use mutable then or maybe even const_cast? Remember that MFC has been around for a long time and when it was designed the Microsoft compiler might not have support for some of the more exotic features of C++ at the time.
In my opinion, if CTest is derived from CWnd (explicitly or not) - showing a dialog box on this CWnd object means changing the state of window/control. Assume CTest is derived from a CDialog, and pressing some button causes this function (CTest::MsgTest) to be called. It effectively means that state of the dialog-box has changed (from user's perspective). It is not important if modal or modeless dialog is shown - the state has changed, hence the method shouldn't be const.
I am trying to color the button by using CColorbutton class function setcolor. It is working fine when I have declared the member variable of button but it is not working when I directly get the handle by GetDlgItem(IDC_BUTTON1). Can anyone tell me the solution of this?
CColorButton* pWnd = (CColorButton*)GetDlgItem(id+i);
pWnd->SetColor(RGB(0,0,0),RGB(200, 153, 204));
First of all: Without declaring a variable for the button control you will not get it to run!
Why? A window Variable and using DDX-Control or using CWNd::SubclassWindow is the way, subclassing works in the MFC. Without subclassing the messages are not handled by the code that is used in CCOlorButton.
Yes you can use GetDlgItem and my do a hard cast to CColorButton, but this is extremely dangerous! Why? The window object you get is just a temporary CWnd object with no additional member variables. If you call a specific member function of a CColorButton, that uses additional data members you may destroy your memory/heap/stack content.
With a MFC control class you always need the specific object somewhere in memory to suavely cast a pointer that GetDlgItem returns!
If you have a member function you don't need a cast. If (for any other reason) you need to cast a CWnd pointer, it is wise to use STATIC_DOWNCAST/DYNAMIC_DOWNCAST to get ASSERTs when something is wrong.
If you do not declare and properly initialize a CColorButton variable then there is no CColorButton object in your program. So you are calling something that does not exist. You asked for the solution of this, but you already know the solution!
I see several code examples showing variables and object creations inside of the InitInstance() function of an MFC appObject (i.e. theApp). I thought anything created inside a function dies when the function exits. And the InitInstance function does appear to exit prior to the program exiting, just after showing the windows.
What am I missing? How does this work?
Yes, you are correct: objects created at function scope with automatic storage duration will be automatically destroyed when the function exists.
There are two possible explanations for what you're seeing (it's hard to narrow it down any more than that since you didn't include any example code with your question):
The objects are actually being created using the new keyword, which means that they have dynamic storage duration and are not automatically destroyed. Instead, they must be manually destroyed using the delete keyword. In addition to seeing new, a dead giveaway of this style is the use of pointers—new returns a pointer to the new object, so you'll see * all over the place.
The object doesn't actually need to exist any longer than the function in which it is declared. It might be temporarily created just so that some of its member functions can be called. The effects of these member functions are global or have effects beyond the class object itself. This is rather common in MFC, since most of the classes are wrappers around the Win32 API.
For example, the CWnd class is just an object-oriented wrapper around a Win32 window, represented by an HWND (or handle to a window). You can create a CWnd object, use it to create and manipulate a Windows window (HWND), and then allow it to be destroyed without affecting the underlying Windows window. The "Remarks" section of the CWnd documentation talks a bit about this confusing behavior:
A CWnd object is distinct from a Windows window, but the two are tightly linked. A CWnd object is created or destroyed by the CWnd constructor and destructor. The Windows window, on the other hand, is a data structure internal to Windows that is created by a Create member function and destroyed by the CWnd virtual destructor. The DestroyWindow function destroys the Windows window without destroying the object.
You did mention the ubiquitous theApp object in your question, though. That one is a little different—it's actually a global object because it is not declared inside of any function's scope. It is automatically constructed when the program begins executing, and automatically destroyed when the program ends.
I'm trying to implement some sort of 'just-for-me' game engine and the problem's plot goes the following way:
Suppose I have some abstract interface for a renderable entity, e.g. IRenderable.
And it's declared the following way:
interface IRenderable {
// (...)
// Suppose that Backend is some abstract backend used
// for rendering, and it's implementation is not important
virtual void Render(Backend& backend) = 0;
};
What I'm doing right now is something like declaring different classes like
class Ball : public IRenderable {
virtual void Render(Backend& backend) {
// Rendering implementation, that is specific for
// the Ball object
// (...)
}
};
And then everything looks fine. I can easily do something like std::vector<IRenderable*> items, push some items like new Ball() in this vector and then make a call similiar to foreach (IRenderable* in items) { item->Render(backend); }
Ok, I guess it is the 'polymorphic' way, but what if I want to have different types of objects in my game and an ability to manipulate their state, where every object can be manipulated via it's own interface?
I could do something like
struct GameState {
Ball ball;
Bonus bonus;
// (...)
};
and then easily change objects state via their own methods, like ball.Move(...) or bonus.Activate(...), where Move(...) is specific for only Ball and Activate(...) - for only Bonus instances.
But in this case I lose the opportunity to write foreach IRenderable* simply because I store these balls and bonuses as instances of their derived, not base classes. And in this case the rendering procedure turns into a mess like
ball.Render(backend);
bonus.Render(backend);
// (...)
and it is bad because we actually lose our polymorphism this way (no actual need for making Render function virtual, etc.
The other approach means invoking downcasting via dynamic_cast or something with typeid to determine the type of object you want to manipulate and this looks even worse to me and this also breaks this 'polymorphic' idea.
So, my question is - is there some kind of (probably) alternative approach to what I want to do or can my current pattern be somehow modified so that I would actually store IRenderable* for my game objects (so that I can invoke virtual Render method on each of them) while preserving the ability to easily change the state of these objects?
Maybe I'm doing something absolutely wrong from the beginning, if so, please point it out :)
Thanks in advance!
The fact that you are storing the different objects as members of the class shouldn't prevent you from storing pointers to them in the IRenderable* vector.
struct GameState {
Ball ball;
Bonus bonus;
vector<IRenderable*> m_items;
GameState() // constructor
{
m_items.push_back(&ball);
m_items.push_back(&bonus);
}
};
This way you also don't have to worry about freeing the pointers in m_items. They will be automatically destroyed when the GameState is destroyed.
Also, your syntax of foreach is funky.
You should really have separate subsystems in your game engine. One for rendering and another one for game logic. Your graphics subsystem should have a list of pointers to IRenderable objects. Your game logic subsystem should have its own list of objects with another interface.
Now you can easily have entities that have state but cannot be rendered and so on. You might even have a separate subsystem for audio. This should also help keep your code clean and modular.
I'm not a c++ programmer but hopefully faux-code will help...
Class Renderable has the function Render
Class Movable inherits from Renderable and also has properties such as x, y, z and functions like Move
Class Ball inherits from Movable
Now your game state can have a list of Renderable objects and, when the time comes to Render, it can just loop through them.
Other actions, like a tick of the world clock, might loop through looking for objects which are instances of Moveable and tell them to update.
If your Bonus is renderable (I couldn't tell for sure from your question) then it could subclass Collectable which subclasses Moveable.