I believe I've found an official Answer to my Problem (Object Factories)

This is a discussion on I believe I've found an official Answer to my Problem (Object Factories) within the Game Programming forums, part of the General Programming Boards category; Searching, searching, searching... Always I had a few questions, how the heck do I create new instances of objects without ...

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964

    I believe I've found an official Answer to my Problem (Object Factories)

    Searching, searching, searching...

    Always I had a few questions, how the heck do I create new instances of objects without writing 30 lines of code (probably a hundred or so in some cases).


    How do I pass an "Object" to a function that simply pushes the object into a vector, while being able to send all of the class "Object" derivedrens unique? Ultimately, Passing *Object to the function while *Object might be a space ship, a wall, a planet, an asteroid, a tree, etc etc...

    The answer is an Object Factory. An Object factory that creates other Object Factories, a super factory to manage -EVERY- object in your entire program. This "Object Factory" would be at the very very very VERY tip top of your Include files, included once into the entire project, but used and weaved in throughout, in amazingly seemless OOP.

    I believe this is the HOLY GRAIL of oop, the pinnacle of C++ as an object oriented language, and to boot, not that difficult to understand the outlying structure of the whole thing.


    I will include an example of a simple Object Factory below..

    The article was written by Robert Geiman and is on www.GameDev.net .

    Props
    Attached Files Attached Files
    Last edited by Shamino; 12-16-2005 at 05:05 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    The actual OO part of that design is pretty standard and not to the max at all (theres tons of design patterns, and standard OO features (multiple inheritance, etc) that it doesnt use. It is definetly close to the max it could go on this feature for sure (macro magic, templates, classes, oo, maps, etc.). God, I hate when macro magic is necessary..

    The point of this is so that it returns the right subclass type, so it shouldnt be assigned to the base class Monster, it should be assigned to the subclass. So it should actually be this:

    Code:
       GoblinMonster *monster1 = monster_factory.Create(GOBLIN_MONSTER, 34.5f, 63.0f, 7.7f);
       OgreMonster *monster2 = monster_factory.Create(OGRE_MONSTER, 83.0f, 14.2f, 54.4f);
    You should be using monster1.UnRegister(GOBLIN_MONSTER); too.

    Your examples kind of fail to show why this is useful at all. Of course you have a system to handle all objects (thats obvious). However instead of returning the base class Object, you can return the correct subclass. You've found the article on how to do that. In order to utilize this you would have to have to do sort of what the Create() method does, and search for the correct subclass by id, but instead of returning NULL, when you find it you return the subclass. So then simply add a new method to class ObjectFactory:

    Code:
    BaseClassType *Find(UniqueIdType unique_id)
          {                                                                                                     
             Iterator iter = m_object_creator.find(unique_id);         
                                             
             if (iter == m_object_creator.end())                                                                
                return NULL;        
                                                                                
             return (*iter).second;
    }
    BTW since these objects have to be searched for, the have an overhead of O(log n) instead of O(1).

    The reason you're seeing the constructor for the OgreMonster is because it actually does exist in the map in the ObjectFactory, but when you assign it to Monster you arent going to be able to access functions that OgreMonster has but Monster does not. Try it out and please let me know if I'm wrong, because that would be great if I was wrong - the problem would be solved.

    I can't figure out how it would work. Of course you can get the subclass you want, but you could do that anyway - that isn't the problem. The problem is the recieving end of a function. Now that you see you cant assign it to the Monster class, that should be apparent. You would have to know what class to assign it to (OgreMonster or GoblinMonster) in the function you are passing say the ID or object to. Which is the whole problem in the first place and that makes this factory pointless as a solution (its a nice factory, but I dont see it being a solution to this problem). You could template a function accept the Ogre type.

    But thats just annoying and I'd rather just stick all of the information CRender, CWorld, and CPhysics need in Object and be done with this problem.

    EDIT: I can't compile it to test anyhow, what compiler do you use?

    EDIT: You could do the most valuable test by keeping monster1/2 as type Monster. Then simply give OgreMonster and GoblinMonster two different functions, and then calling monster1->function1(), and monster2->function2(), and see if the compiler tells you monster1/2 don't contain those functions (like it normally would).
    Last edited by Dae; 12-16-2005 at 07:50 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  3. #3
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    The template class uses function pointers, therefore you can access the functions of the derived classes...


    Code:
    class WalkForwardCommand : public Command
    {
    public:
       WalkForwardCommand() {}
       virtual ~WalkForwardCommand() {}
    
       virtual void Execute()
       {
          std::cout << "\nWalking forward...\n" << std::endl;
       }
    };
    You can call Execute just fine, and I'm going to assume you can access any variables held in the walk forward command, why would it be any different?

    Oh wait, command has a virtual Execute function, let me think on this one...

    I think this is where you're asking too much Dae. (someone correct me if I am wrong)

    What needs to access which functions in your classes?

    A render function needs to access model data, therefore you create a Scene_Object class, which handles nothing but pictures.

    A Game world needs to access physics and collision detection, therefore you create a Physics_Object class, the reason you can't combine Scene_Objects and Physics_Object is because the renderer doesn't need to know physics data and functions, it just needs to know a final result (x, y, z changes)

    Having one class that does it all, simply isnt the essense of OO.. Think, A Goblin doesn't have physics, physics effect Goblins.

    You, unfortunately Dae, cannot create a super Object class unless you use 100 virtual functions for everything any object might use, even if they don't use it... (correct me if I am wrong, someone)

    I might be talking way over my head of knowledge, but you would think if you've been searching for any amount of time at all, and no one could answer your question efficiently, it simply can't happen, I've seen your posts, they make perfect sense...

    I'm going to email the creator a few times and ask him questions.

    Code:
    class OgreMonster : public Monster
    {
    public:
       OgreMonster(float x, float y, float z)
       {
          std::cout << "Ogre monster created at coordinate: " << x << ", " << y << ", " << z << std::endl;
       }
    };
    When the OgreMonster is created, xyz is returned... OgreMonster is a function (constructor really)..... I guess that doesn't count. Is there a such thing as nested functions? Perhaps a function def inside the constructor ?

    OR:

    You could create an OgreMonster factory, with a couple functions specific to OgreMonster... I think that would become redundant, because that would be narrowing down our thing we wanna return, we wanna be able to return a pointer to a general monster while keeping all that data... Hmmm

    FINALLY:

    I think I have the answer, its function pointers, simple as that, easy as pie. Instead of having the Constructor of OgreMonster have just an x,y,z arguement, give it more arguements, one pointer for each function. This way those function pointers would be created in the new Monster object, reay to use. (right? )
    Last edited by Shamino; 12-16-2005 at 09:11 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #4
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    No, your monster1/2 would not be able to access Ogre/Goblin specific functions because you're casting them to the base class Monster.

    The template class uses function pointers, therefore you can access the functions of the derived classes...
    The function pointer is so that you can create the subclass, and its stored in a map along with an id.

    I reread the article and completely understand now. It is not meant to resolve my or your issue. I was actually wrong and it doesn't even store the instances. However it does create them and then return them, so thats why your constructor for Ogre/Goblin was being called. I believe he simply casted the returned class to the base class as an example, which would be file for interfaces. Rereading the intro in that article I can't believe I spent so much time looking at it. I've decided to stop reading these specific design patterns for a while, at least until I finish the prereq Design Patterns.

    You, unfortunately Dae, cannot create a super Object class unless you use 100 virtual functions for everything any object might use, even if they don't use it... (correct me if I am wrong, someone)
    I realized that, and thats why I was seeking a different way. There are many ways to do one thing yeah know.

    Sorry if I was the one that got you hung up on my goal to make it so there was no dataloss when recieving an Object as a parameter. I've decided I've probably been overdoing it and yeah, expecting too much. So I've decided to simply put all information (mass, velocity, coords, etc) that CPhysics, CWorld, or CRender might need for Object's in Object.

    I think this is where you're asking too much Dae. (someone correct me if I am wrong)
    However, I talked to some people at EFnet, and there is a way to accomplish want I wanted. The very simple way is to make a templated method. I could then pass it any class, problem solved. The only reason I wont do this, unless for some rare reason, is because obviously thats going to make multiple copies of the function for each class and its a bit more complicated. Plus I hear they might be the devil.

    I think I have the answer, its function pointers, simple as that, easy as pie. Instead of having the Constructor of OgreMonster have just an x,y,z arguement, give it more arguements, one pointer for each function. This way those function pointers would be created in the new Monster object, reay to use. (right? )
    I've got to say thats overdoing it more than me.

    When the OgreMonster is created, xyz is returned... OgreMonster is a function (constructor really)..... I guess that doesn't count. Is there a such thing as nested functions? Perhaps a function def inside the constructor ?
    Yeah it doesn't count, because of what I said two times. Nope, theres no nested functions in C++.

    A Game world needs to access physics and collision detection, therefore you create a Physics_Object class, the reason you can't combine Scene_Objects and Physics_Object is because the renderer doesn't need to know physics data and functions, it just needs to know a final result (x, y, z changes)
    Well, you can combine them actually. The thing is, whats your point? CRender takes a pointer so it doesnt matter if the object has extra data it doesnt need to use, it just doesnt use it. My problem was that I thought there would be some variables that CPhysics, or CWorld might require in a generic function that not all Objects shared and therefor should not be put as high up as in the Object class. I cant think of any examples, but I was trying to think ahead. As I've said I've decided I cant think of any reason not to, and will not put velocity, mass, coords, etc. that CRender, CPhysics, and CWorld may need in Object.

    Having one class that does it all, simply isnt the essense of OO.. Think, A Goblin doesn't have physics, physics effect Goblins.
    I did not mean for a class that does it all, what I meant for was a function that was generic (and I cant believe I didnt realize to use a templated method because thats a generic function) so it could accept any subclass of Object. BTW physics may effect Goblins, but Goblin still needs to know its mass, velocity, etc. and then physics uses that data to change Goblins position. Simple.
    Last edited by Dae; 12-17-2005 at 01:07 AM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  5. #5
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    The only arguement I have is about Goblin Knowing its mass and velocity, Goblin doesn't need to know those things, some other higher power does, (a physics engine)..

    But for the most part you are right.

    Although, You mean we could solve the problem with function pointers in the constructors parameters, so they would be passed to the template class?

    If theyre the devil, they sure allow you to do a beautiful thing.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  6. #6
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    Few words from Robert Geiman

    first, Dae is correct, you don't want to convert the pointer returned from the Create() function into the derived class (ie, OgerMonster *m = f.Create<OGER_MONSTER>(). If you already know the derived class type then you don't need the object factory class.

    Second, I'm not sure I fully understand your problem.

    Normally when you're in a situation where you want to use the object factory class, you'd create multiple instances for specific groups of classes. In other words, you don't derive every class in your game from a BaseClass type and create one BaseFactory class.

    Instead you create seperate factory classes, one for each group of common classes. For example, a MonsterFactory instance for all monsters, or a RenderFactory instance for OpenGL and DirectX renderers. This way each derived class should already contain the same generic functions.

    As far as accessing data that's specific to each derived class, that can be done by the class itself. For instance:

    Code:
    class Monster
    {
    public:
       virtual void Execute() = 0;
    };
    Code:
    class OgreMonster 
    {
    private:
       std::string ogre_name;
    
    public:
       void Execute() { std::cout << "Private ogre name s: " << ogre_name << std::endl; }
    };
    Code:
    class TrollMonster
    {
    private:
       bool is_cave_troll;
    
    public:
       void Execute() { std::cout << "Private cave troll value is: " << is_cave_troll << std::endl; }
    };
    If this doesn't help you, perhaps you could give me more specifics on what exactly you're trying to accomplish.

    Rob Geiman
    I responded like this

    Code:
    class Monster
    {
    public:
       virtual void Execute() = 0;
    };
    
    class OgreMonster 
    {
    private:
       std::string ogre_name;
    
    public:
       void Execute() { std::cout << "Private ogre name s: " << ogre_name << std::endl; } 
     
       void Newfunction
       {
            std::cout << "new function" << std::endl; // we wanna be able to access
        }  // this function in every new instance of OgreMonster  (
    
    };
    We want to be able to create functions specific to only OgreMonster that don't need to be virtualized in OgreMonsters Base class (Monster)

    So when we basically create a new monster with your factory, we wanna be able to access functions specific to every single individual monster as well (I.E, no data loss)

    I though function pointers were a good idea, pass a pointer to a function specific to the individual monster, therefore you could access them easy as pie in the new templated class.

    Any suggestions?
    Last edited by Shamino; 12-17-2005 at 03:31 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  7. #7
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Hmm..

    Well his suggestion is the best way to accomplish it, but like you said thats what we are trying to avoid - virtual functions. The thing is that function pointers could possibly work (I dont have much experience with them, especially in a case where you're using like 10 of them), but that would kind of be defeating the point since all we are trying to avoid is 1 vtable lookup.

    I forgot to mention that EFnet also said that the extra vtable lookup isn't liable to be a problem unless you're planning on performing it thousands or millions of times a second (like with vectors or vertex operations).

    I do understand these concepts more than I did before, but not entirely because of course they are all new to me. His article even refers you to read other articles first. If you check one of the other articles its more clear on the purpose of a pluggable factory. The point of it is to take an id and call a class based on that. Which makes complete sense when you think about say networked games. You send an id to a client and the client knows which class to call based on what id is sent. Then what his article is meant to accomplish is a generic ability to use it for any base classes, with the ability to choose which derived class is chosen at run-time, while also being quite quick because it uses a map.

    Honestly theres no purpose for us to use this article because we already have access and know which classes we want to call. The only problem was that we don't know which class we want to accept in say CRender, so we use Object*. Then the problem is that when casting a subclass of Object that has data that isn't from Object (and Object isnt concrete (virtual functions)) we lose it. The thing is even though thats the problem, I cant think of ANY case that CRender, etc. will be accessing data that not all Object's share (velocity, mass, etc.) - I was just thinking ahead. Even if I can find a case where this becomes a problem, I could simply overload the function to accept that subclass, or if I dare use "the devil" templated methods. Problem solved.

    For me the problem never really existed, because as I said was just thinking ahead. For you though I guess it does, you don't seem to want to give Object this data. Goblin may not need to know what his mass is, thats an opinion, but I don't agree entirely. I can think of methods that Goblin would have where it needs to know its mass, and even if it doesn't need to know its mass, it needs to store that data because its a property of itself and must send that data to CPhysics.

    You could use templated methods to solve your problem (which is like many overloaded methods for each different subclass of Object).

    I'm pretty clear on what I'm doing now, but good lucky to you in your search.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    That's quite simply not possible in the static typing system of C++. In order to call a function on an object, you need to have a reference or pointer to that object that is of a type that actually contains the function. Therefore, to call an OgreMonster-specific function, you need an OgreMonster* to the object. If the object is currently only available as a Monster*, you have to do a downcast, which means you also need to find out if the runtime object is of type OgreMonster (or derived). This is possible using dynamic_cast or some other RTTI mechanism, but it always involes an if().

    You have to see it this way. Given an object factory
    unspecified create(Tag type);
    and a variable
    Tag tag;
    the call
    Monster *p = create(tag);
    is for the compiler completely opaque (usually). tag might be OGRE_TAG or GARGOYLE_TAG, but there's not way to know that at compile time. Who knows, the value of tag could have been created like this:
    tag = rand() % 2 ? OGRE_TAG : GARGOYLE_TAG;
    The best you can supply for 'unspecified' therefore is Monster*, meaning you lose some type information.

    On the other hand, one of Dae's basic requirements in this debate is flawed:
    My problem was that I thought there would be some variables that CPhysics, or CWorld might require in a generic function that not all Objects shared and therefor should not be put as high up as in the Object class. I cant think of any examples, but I was trying to think ahead. As I've said I've decided I cant think of any reason not to, and will not put velocity, mass, coords, etc. that CRender, CPhysics, and CWorld may need in Object.
    What you're doing here is overdoing genericity. Or perhaps not, in a way. What it comes down to is this: CRender renders RenderableObject, CPhysics affects PhysicalObject and CWorld contains WorldObject. Whatever's not in these classes (or interfaces, more likely) is of absolutely no interest to these classes. Should you find that your CPhysics needs to access a property that's specific to OgreMonster, your class design is flawed and you need to rethink it.

    There's another interesting topic here, and that's where you draw the line of additional subclasses. Take Blizzard's Diablo 2, for example. (It's a good example, because I know for a fact that it's written in C++.) Do you think they wrote a Skeleton class, a Ghoul class, a Sabercat class, and an Andariel class? Or to go further, did they write classes for BurningDead, Horror, Returned and all the other classes of skeletons you encounter?
    They did not. There might be a Monster class deriving from Character, though I wouldn't even bet on that, and that Monster class is then configured solely by properties: which monster type it is, which model therefore is to be used, what class it is, what level, what special properties it has. There's behaviour scripts attached, and action scripts (e.g. those nasty oversized bugs that cast lightning every time they're hit). All that comes from data files - even the scripts. It's called data-driven design.

    I'm just mentioning this because separate classes for Ogres and Goblins seem too specific for me.
    But it's also a question of extensibility vs effort. It's easier to write a few specific classes than to write the environment that allows extensibility a la Total Annihilation.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    Well, I guess this is where our problems begin to make a fork in the road.

    If I could get his class factory to pass function pointers to the templated class, and then use them accordingly, I'm done, my quest is over, and I'm finding that one out now.

    Good luck to you as well Dae .
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  10. #10
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    CornedBee

    You're saying that we cant have Base class (templated) A = to a Derivedren B, C, D, or E?

    We want to be able to pass a single *Object to a function, rather than a B, or a C, or a D, or an E...

    This = impossible?



    Honestly, if they'd just give us the ability to recompile on runtime I'd be happy LOL.
    Last edited by Shamino; 12-17-2005 at 04:08 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  11. #11
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by CornedBee
    What you're doing here is overdoing genericity. Or perhaps not, in a way. What it comes down to is this: CRender renders RenderableObject, CPhysics affects PhysicalObject and CWorld contains WorldObject. Whatever's not in these classes (or interfaces, more likely) is of absolutely no interest to these classes. Should you find that your CPhysics needs to access a property that's specific to OgreMonster, your class design is flawed and you need to rethink it.
    You're right. I cant think of a case where that problem does exist, and I guess if it does occur then you're right I should rethink it rather than overloading methods. But I'll save that for when I actually encounter that problem.

    BTW that was a typo, I meant:

    As I've said I've decided I cant think of any reason not to, and WILL put velocity, mass, coords, etc. that CRender, CPhysics, and CWorld may need in Object.
    Shamino, don't you think that would be supremely complex?

    Would you mind giving us an example of your ideal Object and derived classes so we can see why exactly you're avoiding putting velocity, mass, etc. in Object so much? Thats what EFnet and Gamedev recommended to do. I don't see any problem with that, the only reason I brought it up was because I was thinking ahead.

    Oh yeah I forgot, thanks for the reminder CornedBee, I was planning on splitting it up into something like PhysicalObject, Renderable, nonRenderable, etc. as I read half an article about this months ago. Yeah that is an interesting topic, I wouldnt mind reading up on how to do that, haha.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  12. #12
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    Shamino, don't you think that would be supremely complex?

    You're saying that we cant have Base class (templated) A = to a Derivedren B, C, D, or E?

    We want to be able to pass a single *Object to a function, rather than a B, or a C, or a D, or an E...
    Maybe in the actual creation of the system, yes, quite possibily, but the usage would be ultimately simple.



    Also, in case you might be misunderstanding me, I would like to have OgreMonster control all of its own data, I don't want to split it up into a million classes, I <DO> want OgreMonster to have its own functions, its own data, so that everything can use OgreMonster correctly, I want the renderengine, the physics engine, the sound engine, everything, to be able to use OgreMonster as a client....

    I ultimately wanna be able to do this (pulls up his project)


    Code:
    class Object
    {
    public:
    
    	bool MarkedForDeletion;
    
    	struct Location
    	{
    		float locx;
    		float locy;
    		float locz;
    	};
    
    };
    
    class Cross : public Object
    {
    public:
    
    	MS3DModel *Model1;
    
    };


    Then Ultimately..

    Code:
        if (Obj != NULL)
        {
    		Scene_Object_Manager::AddScene_Object(Obj);
        }
    As you can see, I'd like to be able to push an Obj into the vector.... Not have to put a cross in there, or an OgreMonster, or a GoblinMonster, etc etc etc....

    Then after that

    we'll have a draw function in the render class simply file through that container of scene objects, grab their model data, and draw it accordingly...

    Robert Geiman told me this

    You really want to be totally ignorant of the actual derived class type as possibe. Any class specific work should be done from within the class itself. For instance, in Quake 1 (which used C not C++) every game object had an Update() function pointer. This function pointer was called every game loop on ALL game objects, and this function pointer would just point to a class specific function for each class type. The same thing would be true of C++, except you'd have a virtual Update() function that each derived class type overrides.
    Now that sounds like a plan.......
    Last edited by Shamino; 12-17-2005 at 04:45 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  13. #13
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Then what did this mean? It implies you dont want Goblin to know its own information.

    Quote Originally Posted by Shamino
    The only arguement I have is about Goblin Knowing its mass and velocity, Goblin doesn't need to know those things, some other higher power does, (a physics engine)..
    What you said in your last post, about it knowing its information and using it as a client, is exactly what I'm doing.

    I think I get what you mean in your last post (even though your previous posts go against it), that you want the data to be in Goblin and not in Object? Is that what you mean? It couldnt be, because Goblin derives from Object and therefor has that data.

    Your code works fine, just put MS3DModel *Model1; in Object, I mean what Object's couldn't be Rendered anyway? If there are some you can think of, just use CornedBee's advice and make a class RenderableObject and put MS3DModel *Model1; in that, and derive Goblin from that, and pass Goblin to CRender, which has parameter RenderableObject*.

    I don't see you having any problem doing that Shamino.

    usage would be ultimately simple.
    You don't even need a class factory to do what you want to, which requires you to have a few complex files, and register classes, and create classes, and adding it so you can add virtual functions for reach function is like you just agreed going to make it more complex. Besides that, I don't think the usage would be simple. When registering would you not have to pass a virtual function for each function your class contains? Wouldnt that be like up to 20 parameters, which could change if your classes functions change names or get removed or added. The class factory would also need to be able to accept any amount of parameters of virtual functions (...) too, so that would be fun to impliment. That is unless you made a function to add a virtual function one at a time, ie if your class had 15 virtual functions thats 15 function calls. On top of all of that, you do all of this simply to avoid a vtable lookup for each function when you're only doing this for Objects where they arent being called millions of times a second anyway (where it becomes a problem). I don't see where the complexity ends.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  14. #14
    Dae
    Dae is offline
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by Shamino
    Robert Geiman told me this



    Now that sounds like a plan.......
    Thats a great idea.

    Only one vtable lookup (which I've said two times now isn't a problem unless you're calling it many times a second) thats pretty powerful.

    I don't think I'll worry too much about virtual functions for my Objects. Especially when its only a few.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  15. #15
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    I contradicted myself in hopes of having his object factory be my answer, lol....

    All I want is simple, but no one is saying how to do it....

    I want to have a base Monster class

    I want to have lots of little monster derivedrens...

    I want to pass a MONSTER to my push_back call..

    I want to draw what is in that vector!

    I want what is in the vector to have all the little functions that the monster derivedrens have, therefore everything on the scene can do wtf they wanna do, and are created to do, (see monster derivedrens)

    5 steps to uber object management....


    I could pass the derivedrens of Monster to the vector instead, but then I'd have to add a case statement for every single monster, and ultimately have a 100 line long switch, figuring out which Monster derivedren to add to the vector.... (there must be a better way)....

    This would solve my problem, but also be clunky and become long and unmanagable...
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Page 1 of 5 12345 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using this as synchronization object
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 03-22-2008, 07:49 AM
  2. problem with answer going to default?
    By Patrick1234 in forum C++ Programming
    Replies: 4
    Last Post: 10-02-2002, 09:11 AM
  3. slight problem just can't see the answer
    By anthonye in forum C++ Programming
    Replies: 1
    Last Post: 07-05-2002, 08:45 AM
  4. I've ran into a problem
    By Mike Jones in forum C Programming
    Replies: 1
    Last Post: 03-27-2002, 03:08 PM
  5. code help :)
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 02-28-2002, 12:12 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21