🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

C++ Workshop - C++ Keywords, Variables, & Constants (Ch. 3)

Started by
65 comments, last by Dbproguy 16 years, 1 month ago
Quote: Original post by adam23:
I am working on a game engine that encapsulates everything, DirectInput, DirectSound, Direct3D, and so on. Right now I have seven header files and five cpp files. What I was trying to accomplish was one point of contact with the engine.


This is bad, m'kay...[smile]

In your example you create a header file called "Engine.h" which includes many other header files. Any time you modify one of those files, you will be forced to recompile anything that included that file AND anything that contains "engine.h"...which if I understand you correctly will be many files. In essence, changing any of those header files means a recompile of your entire code-base, whether or not the source file actually used the class, function, etc...which you modified within the header file.

Additionally, Engine.h is now a fairly large header, and the entire contents of engine.h will be included EVERYWHERE you include engine.h.

What you're talking about here is very close to a pre-compiled header, without the benefits of being a pre-compiled header; ie. pre-caching of symbols. As well, even when using precompiled headers it is very uncommon to include your own header files, as chances are high you will modify those files frequently, thus requiring a full recompile of your entire code-base. It IS however common to include system libraries in your PCH, such as the DirectX and Windows headers you show in your example.

Quote: Original post by adam23:
See in this situation ResourceManager needs LinedList, Font needs Geometry.h. Am I doing this correctly by having all my includes in the header for the engine and then linking everything here. How do I get around worrying about the order?


Unfortunately no. The first thing is to determine whether ResourceManager needs LinkedList or just a reference or pointer to a LinkedList. If you declare a member variable of type LinkedList, but it is either a pointer(allocated on the heap) or a reference (allocated externally), then you don’t need to #include LinkedList.h, you only need to forward declare class LinkedList at the top of ResourceManager.h.

However, if you do need a local variable of type LinkedList allocated on the stack, within ResourceManager, then #include it IN ResourceManager.h. This removes the problem of "order mattering" when it comes to header files, and means no matter where you #include ResourceManager.h you're guaranteed that LinkedList will be declared.

The same holds true for the relationship between Geometry.h and Font.h. If Font uses Geometry.h then #include it. If it just references the classes, etc...inside of Geometry.h, then use forward declarations instead.

Quote: Original post by adam23:
I could include LinkedList in ResourceManager and Geometry in Font, but I also need these classes for variables in Engine.h. For example I am creating a linked list of states as a private member of the Engine class.


Again, do you NEED LinkedList in Engine.h, or do you just need a reference? If so..forward declare. As well, what is Engine.h? Is there a corresponding Engine.cpp? If Engine.h is just a "Superheader" then you need to rethink your design as I outlined before. But if Engine.h just contains a class which needs LinkedList, then no worries, just #include "LinkedList.h". As long as you have #pragma once (Visual Studio only) or include guards in each of your header files, then it doesn’t matter how many times you tell the compiler to include a header within the current source file, it'll ignore repeated attempts.

To help you get some perspective, its quite common to have 1 header file for each source file, a precompiled header, and that's about it. If you find you have far more header files than source files or vice-versa, you might consider re-evaluating your dependencies.

In general, '#include' in Source Files, not in header files. You help prevent dependency chains, and you keep your code efficient and compiling quickly. However, if you NEED the contents of a header file within another header file, then include it, don’t create an "order matters" dependency within your source files.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Advertisement
Thank you both again for clearing the question marks :)
Have we sent the "Don't shoot, we're pathetic" transmission yet?
I was wondering if it will be possible to refer us back to this recent discussion when we have covered some more of the chapters in the book? I think this is the single best resource/opportunity to learn c++ I've seen in the past decade, the answers are more than generous and from what I've seen so far the question/answer style could easily be edited into a book.

But while I've put together a few lego bricks of logic in my mind, all of a sudden there's a mass more what with reference to classes etc. I'm trying to make sense of it now because I don't want to be asking all those tutors who are giving their valuable time the same questions again & again. But there's a lot to take in & I feel like I'm standing in a hole learning how the foundations are made and at the same time trying to figure out the wallpaper in the upstairs bedroom gets pasted on. I can only digest so many pieces of information at any one time.

So, if in the future I ask a question that's already been answered in earlier weeks please don't assume I haven't been reading everything. I'm just not in a position to understand everything I'm reading. Just point me to (eg) week 2, page 1, about halfway down and I'll thank you & maybe I'll get it then.

simesf
I agree. The answers in this thread are very detailed and several go right over my head. Sure, I've heard of header files, classes, prototypes etc. and I guess that they'll be covered in due course.

I know that I was "guilty" of hijacking things a little while ago when I wanted to get my head around namespace and the relationship between various elements of the language. There are so many things that I want to learn. I'm tempted to read the book way ahead of the workshop but am purposely not doing so as I want to soak everything up and become competent in what I'm learning. I doubt that anyone here is into "cramming" for an exam - I'm certainly not!
@simesf and CondorMan,

it is a common problem with C++ - you ask what seems to be a simple question and you have to cope with answers that speaks about bizarre things. Obviously, we can't avoid this since th other possibility is to say "don't ask the question now, jOO fOOlz0r", which is quite frustrating. For the moment, I'd say that you don't need to fully understand all the answers that are given by the other tutors. Knowing that there is an (logical) answer is enough - you'll be able to find it when you'll have a better understanding of the language.

Don't be afraid of asking the same question again and again. If you carefully read the forum message and still have a problem to understand something then we'd be very happy to help you (I really mean it when I say "very happy").

BTW jwalsh, Amazon lists the entire table of content, and I believe that since you are using the book as learning material, copying the table of content would be considered as "fair use". Of course, I can be wrong (I'm not a lawyer [smile]).
Quote: Original post by jwalsh

In your example you create a header file called "Engine.h" which includes many other header files. Any time you modify one of those files, you will be forced to recompile anything that included that file AND anything that contains "engine.h"...which if I understand you correctly will be many files. In essence, changing any of those header files means a recompile of your entire code-base, whether or not the source file actually used the class, function, etc...which you modified within the header file.


Wow, This is why this workshop is so important. I think a lot of us new programmers are taught bad habits from the beginning. I really appreciate you (and everyone) taking the time to answer our questions. I am going to spend a few hours today reorganizing my project. I am really disappointed with some of the habits that my class and the book that we are studying out of is teaching.
I do notice that the project takes quite a while to compile. My "Engine.h" has a source file called "Engine.cpp". Just for fun, I'm going to post my entire Engine.h class. The question I really have now is that I am creating a linked list like this:
LinkedList< State > *m_states; // Linked list of states.
Would declaring the new linked list as a pointer to an object require including LinkedList in the header file. I know that objects can be used by reference, but what about pointers. I hope the source for the header file clears that up a little bit.
#ifndef _ENGINE_H#define _ENGINE_H//==========================================================//Engine.h//Created by Adam Larson//==========================================================//-----------------------------------------------------------------------------// DirectInput Version Define//-----------------------------------------------------------------------------#define DIRECTINPUT_VERSION 0x0800//------------------------------------------//System Includes//------------------------------------------#include <stdio.h>#include <tchar.h>#include <windowsx.h>//-----------------------------------------------------------------------------// DirectX Includes//-----------------------------------------------------------------------------#include <d3dx9.h>#include <dinput.h>//------------------------------------------//Engine Includes//------------------------------------------#include "LinkedList.h"#include "ResourceManager.h"#include "Input.h"#include "Geometry.h"#include "Font.h"#include "State.h"//-----------------------------------------------------------------------------// Macros//-----------------------------------------------------------------------------#define SAFE_DELETE( p )       { if( p ) { delete ( p );     ( p ) = NULL; } }#define SAFE_DELETE_ARRAY( p ) { if( p ) { delete[] ( p );   ( p ) = NULL; } }#define SAFE_RELEASE( p )      { if( p ) { ( p )->Release(); ( p ) = NULL; } }class Engine{public:	//Constructor initializes Everything	Engine();	~Engine();	//Function called to run engine	void Run();	//Function returns pointer to D3D device	IDirect3DDevice9 *GetDevice();	//Function returns pointer to DirectInput interface	Input *GetInput();	void SetDeactiveFlag( bool deactive );	HINSTANCE instance; //application instance	//Function return the current state	State *GetCurrentState();	void AddState( State *state, bool change = true );	void RemoveState( State *state );	void ChangeState( unsigned long id );private:	//Functions	D3DFORMAT FindDepthStencilFormat( ULONG AdapterOrdinal, D3DDISPLAYMODE Mode, D3DDEVTYPE DevType );	bool m_loaded; // Indicates if the engine is loading.	HWND m_window; // Main window handle.	bool m_deactive; // Indicates if the application is active or not.	unsigned char m_currentBackBuffer; // Keeps track of which back buffer is at the front of the swap chain.	Input *m_input; // Input object.	LPDIRECT3D9 pD3D;  //Direct Input object	IDirect3DDevice9 *m_device; // Direct3D device interface.	D3DPRESENT_PARAMETERS   m_D3DPresentParams; // Direct3D Present Parameters	bool InitD3D();//returns true if D3D is created successfully	bool InitDInput();//returns true if DirectInput is created correctly	Font *m_font; //used to print text on screen	LinkedList< State > *m_states; // Linked list of states.	State *m_currentState; // Pointer to the current state.	bool m_stateChanged; // Indicates if the state changed in the current frame.};//============================================================//Externals//============================================================extern Engine *g_engine;#endif


Adamhttp://www.allgamedevelopment.com
Quote: Original post by adam23
The question I really have now is that I am creating a linked list like this:
LinkedList< State > *m_states; // Linked list of states.
Would declaring the new linked list as a pointer to an object require including LinkedList in the header file.

The above is a pointer. You don't need LinkedList.h.

Now, if you wanted to actually have the LinkedList object as a member of the Engine class (not a pointer to a LinkedList), then you would need the entire LinkedList declaration, and thus LinkedList.h.
Quote: Original post by Emmanuel Deloget
@simesf and CondorMan,

it is a common problem with C++ - you ask what seems to be a simple question and you have to cope with answers that speaks about bizarre things.

More specifically, C++ can not be taught in linear order. You can start here and just progress to there without going back over and over. Learning C++ involves learning a "diluted" version of the facts, then, when you have a better understanding of some fairly obscure principle or philosophy, re-learning what you had earlier been taught in that light.

For instance, Fruny pointed out in a post somewhere that x += ++x; is not legal in C++. He just didn't explain why, because that's a fairly involved conversation. When you do learn why, though, it changes the way you think about C++ expressions and statements.

For the curious, the answer is Sequence Points.
adam23,

Please try to not hijack this thread with something that have no direct relation with ch3 of the workshop book. I'm going to answer this question (and evey question you might ask in the other forum if I see them and if I know the answer) but my answers may confuse the other workshop attendees, and this is somethin that I'd want to avoid - your code contains concepts that are more advanced than the concepts that are in the 3 first chapters of the book.

Quote: Original post by adam23
I do notice that the project takes quite a while to compile. My "Engine.h" has a source file called "Engine.cpp". Just for fun, I'm going to post my entire Engine.h class. The question I really have now is that I am creating a linked list like this:
LinkedList< State > *m_states; // Linked list of states.

Would declaring the new linked list as a pointer to an object require including LinkedList in the header file. I know that objects can be used by reference, but what about pointers. I hope the source for the header file clears that up a little bit.
*** Source Snippet Removed ***


Forward declaration is probably explained in a later chapter.

In your specific case, you can use a forward declaration instead of including LinkedList.h. The point is that in this case, the forward declaration syntax is not trivial (even if it is not difficult). I still recommend that you #include the file for the moment.

If you feel brave enough, the only words I'd say are: in your particular case, the forward declaration syntax for LinkedList<> is the declaration of LinkedList<> without the part between { }. A goog place to put forward declarations is to put them right after the #include list.

I let you do this as an exercise [smile]
I am very sorry for getting off subject, but I am using this workshop to fill in any holes I have in my programming skills. I will make sure to direct any questions that exceed the contents of the course to other threads. I really appreciate everyone taking the time to answer my questions, and I really didn't mean to get off subject that much. :(
Adamhttp://www.allgamedevelopment.com

This topic is closed to new replies.

Advertisement