Thread: Include Problems

  1. #1
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195

    Include Problems

    Ok i always have this problem

    i make a .h file containting the declaration of a class

    then i make a .cpp file contaning the acually code for the decalred class functions

    then i include the .h files at the top the first .cpp i made, in this case a file implementing windows code, and not at the top of the .cpp file for the respective class. note: i have never gotten that to work eaither

    shouldent the .cpp class files be able to see these .h class files, because they are not.

    i thought that the .cpp class files would be below the .cpp window file and have all of those in sight

    since i am useing modules that return a premade modular instance, i need the declarations of the classes to come before i make these and i need the declarations of the class functions after, so they can see them

    i have never been able to get all of this to work, so i would usually just have every thing in the include file but by using modules i need to have them separate

    i dont know mabe i am crazy and need to be shot, but befor that can some one plz help me, i truly am lost on the subject of includes and the like HELP PLEASE!!!

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I was going to type something up, but then I remembered this faq entry.

    Hopefully that will help; if not, you might have to get more specific (i.e., give an example of the problem).
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    ok normally you would of course make a .h file and a .cpp file

    but my case is different

    the internals of my classes make reference to instances of modules

    this means two things

    one, i have to have the class declaration before i make the instance.

    and

    two, depending on which instance i am returning for the next one, i have to have the functions of my class after the declarations of these instances so that the functions can see these instances.

    so i cant just put the header above the .cpp file, because one or the other wont be able to see the other.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code samples please. I'm lost. Referencing modules in a header file? I shudder.

  5. #5
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    ok i found a out how to do it, this was acually one of my first solutions but i was afrade it was to sloppy.

    i include all the module derived classes header files at the top

    then i make the instances of those modules

    then i make another header file for each class, which includes there functions

    The Result: when i make the instances, they can see there respective declaration in the headers. Then when i reference these instances within my class functions they can see them. Its all good
    Code:
    #include "DirectInit_M.h"
    #include "ShutDown_M.h"  
    
    Module* DirectInitM = new DirectInit_M;  //instances
    Module* ShutDownM = new ShutDown_M; //instances
    
    
    //the functions in these headers can now return or do what ever 
    //to the instances above
    #include "DirectInit_M_Func.h" 
    #include "ShutDown_M_Func.h"

  6. #6
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I think you want to use extern variables. Something like what I posted in this thread, perhaps.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  7. #7
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    i think both work fine but i dont like extern that much and dont really want to use it on something that is so fundamental in my engine, thanks for the post though

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Danger Will Robinson.

    If DirectInit_M constructor fails or ShutDown_M fails you have no way of:

    1. Testing to see if it did fail.
    2. Cleaning up if it failed.
    3. Resuming program execution in case of failure
    4. Bailing out when it fails.

    Only use global objects like that when the constructor is guaranteed to never fail. Otherwise you are asking for problems.

  9. #9
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    the default constructor will never fail, right?

  10. #10
    ---
    Join Date
    May 2004
    Posts
    1,379
    Quote Originally Posted by loopshot
    the default constructor will never fail, right?
    Who knows? I guess that's why you should check it.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I took my class design patterns from several sources, but the two primary sources have been Borland and Microsoft.

    For Borland I really liked how they setup OWL or their Object Windows Library. However, I did not like their use of constructors as many of them had far too many parameters.

    Enter Microsoft and MFC. MFC is awesome. Nearly every object has a parameterless constructor that really makes it simple to instantiate the object. None of their constructors allocate memory or do anything that has a possibility of failing.

    I like this design philosophy and have used it. Nearly all of my constructors are parameterless and my destructors are responsible for cleaning up. Some of my classes have shutdown functions or cleanup functions when the object needs to clean up prior to the destructor being called. This also allows the programmer to understand exactly when the object is going out of scope because prior to deletion he must call Cleanup, Shutdown, or something like COM's Release(). I like this pattern a lot because you can directly control object lifetime. Destructors are awesome but sometimes their code, usage, and cleanup strategy are somewhat hidden in the class code which makes it difficult to understand. By calling cleanup or shutdown the programmer knows that he or she can then delete the object safely. Granted you can call delete and if the destructor cleans up correctly it will work, but I like seeing this in code.

    Code:
    CObject *Object=new CObject;
    Object->Create(...);
    Object->DoSomething();
    Object->Cleanup();
    delete Object;
    You can certainly see exactly what is happening with Object.

    Even if this object is created on the stack you can still see the progression:

    Code:
    CObject Object;
    Object.Create(...);
    Object.DoSomething();
    Object.Cleanup()
    Obviously the compiler will pop the object off the stack at the correct time in this example.
    Either way you can see exactly what is happening.

    Constructors cannot return anything and some people try to circumvent this by setting some magic variable in the class. A better method to use if you absolutely must allocate memory or use some resource in the constructor is the exception mechanism in C++. I'm not a big fan of throwing tons of exceptions everywhere but sometimes they are quite useful. Just don't overuse them and you won't have every object throwing this or that which actually adds to the confusion rather than aid in removing it. MFC does suffer somewhat from overusing the exception mechanism. What happens is that the compiler then traces back to the exception code but it is not always obvious as to what threw the exception from the code trace. MFC often throws the exception which leads to another section of code which obfuscates where the error is coming from. Luckily the MS debugger in MSVC 6, 2003 and 2005 is smart enough to lead you back to your code showing what caused the exception. You would have to get deep into MFC in order to understand what I'm talking about here. OWL also had this problem.

    Instead of using several global objects you could use the following form:

    Code:
    class CApp
    {
      //Stick your 'global' object pointers here
      //Init them in the Create() or Init() function of this class
    };
    Then use CApp as a global object. So you have one global object which is the application and nothing more. You can gain access to the other objects from CApp if the design provides this mechanism. When all of the objects are in CApp you have encapsulated the entire application and thus can safely instantiate it and it's members w/o requiring tons of calls from the programmer and you can shut it down or clean up with one call to Cleanup. Then you can either allow the compiler to clean the object off the stack or you can delete it if you created it on the heap.

    I highly recommend buying a book on coding designs and patterns. Everyone uses different and unique patterns but there are some very good basic concrete principles that are invaluable to you as a programmer to learn and use.

    You don't get good at writing C++ classes overnight. Often you learn from your own horrendous objects and then begin to widdle the problem down to very simple, very compact objects and use aggregation and/or inheritance to make the object much more manageable.

    Don't use aggregation just because you hate inheritance.
    Don't use inheritance just because it's uber C++.

    Aggregation: Derived is part of Base.
    Inheritance: Derived is a type of the Base.

    Let me use a car as an example.

    A car has:

    1. Tires
    2. Engine
    3. Passengers

    Aggregation: Cars have tires (or a car has a tire). Makes sense.
    Inheritance: Cars are tires. (a car is a tire) What?

    Aggregation: A car has an engine. True.
    Inheritance: A car is an engine. Perhaps to some gearheads, but not in our case. This does not make sense.

    Aggregation: A car has a passenger or has passengers. True.
    Inheritance: A car is a passenger or a passenger is a car. Umm, no not usually.

    Ok so we have base class Car:

    Code:
    class CCar
    {
      protected:
        CTire *m_pTires;
        CEngine *m_pEngine;
        std::vector<CPassenger *> m_vPassengers;
    };
    Now we want a sports car.

    Aggregation: A sports car has a car. Not on this planet.
    Inheritance: A sports car is a car. Yes as a matter of fact it is.

    Which leads us to this design decision:

    Code:
    class CSportsCar:public CCar {}
    Hope this helps and isn't overkill.

    Is a = inheritance
    Has a = aggregation
    Last edited by VirtualAce; 02-17-2006 at 01:49 AM.

  12. #12
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    A very informative post bubba, but i just thought you should know that my design is very encapsulated, safe, and simple, let me explain, i think you may like it. NOTE it will only make sence at the very end

    first off, the constructors of my Module classes are always empty, no chance of failue like you said.

    second, all the members within the Module base class are protected. so not even a pointer to the class can call any functions, init, execute, ect, or member variables. so you cant get to it in any way shape or form with a pointer.

    since i only deal with module pointers that point to a derived module, i can only call functions and members explicidly stated in the module base class, the safety is still enforced becouse i still cant call any thing even i the derived class has public members, which it should not but i dont take chances.

    all derived classes of module have a function called Execute, which returns a pointer to the next module to run. as you know, these are the "global pointers" we where talking about, but of course nobody can do anything but move them around becouse of the protected-ness of module.

    there is a specific class that is called ModuleHandler, which containes a vector list of pointers to modules, the current module pointer, and the last module pointer and the functions, Regester, and ModuleLoop.

    there is another member of Module that i did not metion, it is called Registered and begins as false.

    the ModuleLoop function of ModuleHandler, takes the current module and runs it and all that good stuff, but the main thing of note is that it wont run unless Registered == true in CurrentModule, it will return an error if it cant run one.

    so when a module is created it must be registered in ModuleHandler as well, when registered it adds that member to the vector list and turns the Regestered value to true.

    the last note and most important one of all and will make this all instantly clear is that the Module class is friends with ModuleHandler.

    so all of these 'global modules' cannot be touched my any thing or in any way but in the ModuleHandler class. this creates a ultra safe and simple envorment where the way Modules can be used are very protected so people can use them in unintended ways. ModlueHandler uses that vector list later to Shutdown all of the modules, delete them and set them too null.

    sorry i cant post the code, i am inbetween classes at the moment

    thanks for your informative post, i just wanted you to see my full implementation so you could see that it is very safe, fast, and all that good stuff.

  13. #13
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    And what's this for?

  14. #14
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    Ok it goes like this, the Module class is basically a place for a 'chunk' of code to go. This could be any thing from a rendering process or intilizations or some thing or any thing, and returns the pointer to the next one.

    Code:
     class Module
    {
    protected:
    	bool Registered;
    	
    	friend class ModuleHandler; //the Module and ModuleHandler classes are now friends, yay!!!
    
    protected:
    	virtual void Initialize()=0;
    	virtual Module* Execute()=0;
    	virtual void Shutdown()=0;
    };
    The ModuleHandler is the class that manages all Modules, it loops through them, makes sure they are registered, delets them at the program end, ect. Module Handler is also the only way to acess a derived Module. NOTE: the shut down part is not in there yet.

    Code:
    class ModuleHandler
    {
    protected:
    		vector<Module*> ModuleList;
    		vector<Module*>::iterator ModuleListIterator;
    		Module* CurrentModule; //holds the current module of use
    	    Module* LastModule;	  //holds the last module of use
    public:
    	
    	ModuleHandler(Module* FirstModule)
    		{
    			CurrentModule = FirstModule;
    			LastModule = CurrentModule;
    		}
    	
    	void RegisterModule(Module* module)
    		{
    			if(module->Registered != true) //if this is false, the module is already registered 
                                    {
    	             ModuleList.push_back(module);
                                    module->Registered = true
                                    }
    		}
    	
    	void ModuleLoop()
    		{
    			if(CurrentModule != NULL && CurrentModule->Registered == true)
    		{
    		
    		CurrentModule->Initialize();					//initialize module
    		CurrentModule = CurrentModule->Execute();		//execute module
    		
    		if(CurrentModule != LastModule)					//true, we have switched modules
    		{
    			LastModule->Shutdown();
    			LastModule = CurrentModule;
    		}
    	
    		}
    	
    	  else
    	  MessageBox(0, "Module Not Registered", 0, 0);
    	  }	
    
    };
    Last edited by loopshot; 02-17-2006 at 06:25 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C programing doubt
    By sivasankari in forum C Programming
    Replies: 2
    Last Post: 04-29-2008, 09:19 AM
  2. some problems with #include
    By Cmaniac in forum C Programming
    Replies: 6
    Last Post: 04-15-2007, 11:28 PM
  3. Headers that use each other
    By nickname_changed in forum C++ Programming
    Replies: 7
    Last Post: 10-03-2003, 04:25 AM
  4. #Include "class" problems
    By Unregistered in forum C++ Programming
    Replies: 17
    Last Post: 11-26-2001, 10:40 AM