Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


The 5millionth post on OO design principles..


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
52 replies to this topic

#1 Remnant   Members   -  Reputation: 122

Like
Likes
Like

Posted 06 December 2000 - 02:30 PM

I guess I have two questions. The easy one first : 1) Can anyone recommend a book that has a solid section on principles of code design when following OOP? I''ve been programming for the past 6-8 years, but become interested in OO for only this past year, so I''m interested in a book that gives a more in-depth look at OO use in the real world: Writing proper OOP code without resorting to inefficienct bloat or work-arounds is what I am interested in. I''ve heard good things about Design Patterns : is it worth the purchase price? 2) Now for my actual situation. It is a common thing in my current game engine for an object in the world, to contain inside of it other objects (in an array, whatever) that define its behavior. Example : a spaceship has a set of engines, generators, guns, etc. These objects are literally modular parts that are plugged into the ship in-game; the problem stems from the interaction between a parent object and its parts. The problem is, these part need access to nearly all of the information of their parent ship. In the case of an engine, it needs to modify the ship''s velocity vector when its Act() function is called; a generator needs to supply power to other parts on the ship; an autonomous turret needs targeting information from the ship''s sensors; etc. To achieve this, I have been letting the parts keep an Owner pointer, from which they can call appropriate functions on the ship; the engine calls a setvelocity() function, a generator setenergy(), etc. However. I don''t really like this system. I''m keep a lot of extra pointers around, for one thing. I''ve also heard that having to do this is a sign of improper OOP: what would be the proper way of having this sort of modular part design? I can''t simply pass in the data on calling the module''s Act(), since the ship doesn''t know what part in its part container is what, and trying to do so is a bad idea (see the other OO thread going on about linked lists) The issue becomes more acute for "special" modules. These have varying and often quite wild effects on their parent ship. For example, there might be a part that allows for cloaking, a part that gives temporary invulnerability, etc. These parts have to directly change crucial inner data for the ship (its draw function, its sensor appearance, damage reception routine, etc), So the abstract question is : how do you best achieve data-sharing and modification between an owner class and a contained class? And then how to achieve radical behavioral (functional) changes in the owner class by functions in the parts class? OO always make so much sense in abstract, but I get into problems when getting into the actual implementation... After getting into quagmires like this, it makes me grumble and just want to go back to C. - Remnant
- (Steve Schmitt)


Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9673

Like
Likes
Like

Posted 06 December 2000 - 02:59 PM

A couple of thoughts.

Let''s take your ship example. Ideally the game engine itself shouldn''t be calling the update function on each individual part of the ship. Instead it should just say Ship->Act(). And then the ship should update it''s individual parts. Now that the ship object is calling the update on each part, it can, if it feels like pass a pointer to itself to the parts. That way the engine doesn''t need to store an owner pointer, but it has access to it when it needs it.
Also ideally the ship should know what kind of parts it has attached. So when it tells the engine to update, the engine might just update it''s thrust internally. Then the Ship uses thrust and mass to determine it''s velocity. So the Ship->Act() function might look like:

Ship::Act() {
m_pEngine->Act();
velocity = m_pEngine->GetThrust() / m_iMass;
}

Or if the generator supplies energy, and components use energy your code might look like:

Ship::Act() {
m_iEffectiveMass = m_iMass;

m_pGenerator->Act(this);
m_iEnergy = m_pGenerator->GetSuppliedEnergy();

m_pEngine->Act(this);
m_pShield->Act(this);
m_pSensors->Act(this);
m_pMisc1->Act(this);
m_pMisc2->Act(this);
m_pBattery->Act(this);

velocity = m_pEngine->GetThrust() / m_iEffectiveMass;
}
Engine::Act(Ship * owner) {
int EnergyReceived = owner->RequestEnergy(10);
m_iThrust = 10 * EnergyReceived;
}
Battery::Act(Ship * owner) {
m_iEnergyStore += owner->RequestRemainingEnergy();
if (m_iEnergyStore >= StoreMax) m_iEnergyStore = StoreMax;
}
InertialDampner::Act(Ship * owner) {
int EnergyReceived = owner->RequestEnergy(3);
owner->m_iEffectiveMass /= (EnergyReceived + 1);
}


#3 freakchild   Members   -  Reputation: 557

Like
Likes
Like

Posted 06 December 2000 - 03:46 PM

1) Design Patterns is well worth buying. While it''s not about code design it will teach you about many common OO problems and patterns that you can use whilst doing your design. Try the Pattern Languages of Programming (PLOP) series for similar reasons and the C++ Gems books might even interest you. Do you have C++FAQs?

2) I can''t add to this and think SiCrane should be commended for writing a pretty good clear response.


#4 Shannon Barber   Moderators   -  Reputation: 1390

Like
Likes
Like

Posted 06 December 2000 - 05:52 PM

I've finally finished reading Design Patterns, and though most of it doesn't apply to games (or least I didn't understand how :p), a few do.

I use the Factory pattern. Alot. I also use Chain-Of-Command (as described by SiCrane above) quite a bit, in all my windows programs (i have used this method before, just never called it CoC).

The material in the book isn't exactly unique, its more like a compendum of OOD methods (which are called patterns). None of the techniques were particularily hard to implement, and it gives you a series of concrete examples of 'when this pattern applies' that I think is very useful. The factory method, unlike CoC, never occurred to me before I read that book. It was one of the first ones, and my jaw dropped when I read it.

A FSM pattern would be nice...

...
To acheive the radical special effects you could use a decorator class. A decorator encapsulates the parent (CShip) class, and gets first crack at any method calls.

Something like
    
class CCloakedShip : public CShip
{
//override

//cloaked ships can't be detected

BOOL OnDectect(float fDetectionLevel)
{return(FALSE);}
//cloaked ships can't fire

BOOL OnFireWeapon(DWORD dwWeaponID)
{return(FALSE);}
//let everything else pass onto CShip

};

Using this method you can add new effect that are not part of the original design, without affecting that design.
A CShip* can point to a CCloakedShip, and so long as OnDetect() & OnFireWeapon() in CShip are virtual, everything works.

This is where you pay a performance penalty, its not much, only one extra deference for each OnFire & OnDetect call. So having virtuals on your render path is bad. Having a virtual for OnDetect & OnFire won't matter because they only happen a few times a second max.

If cloaking or something else, where a common thing I'd add support directly in the class, like a bool m_bCloaked.



Magmai Kai Holmlor
- The disgruntled & disillusioned


Edited by - Magmai Kai Holmlor on December 7, 2000 1:43:19 AM

#5 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 06 December 2000 - 06:35 PM

Just bought the Design Patterns book over the weekend and I''d recommend it. Even only 20 pages in I was impressed.

Now I''m only a decade behind on the SE stuff!

#6 Shannon Barber   Moderators   -  Reputation: 1390

Like
Likes
Like

Posted 06 December 2000 - 06:39 PM

That feeling quickly fades after the first 20 pages, it starts becoming a big yawn after the initial wow factor wears off.
Still very useful stuff, but it reads like the text book that it is - and not like TotWGPG or even Petzold''s Win32 book.

I was coming back to add that; Every time some one has posted an OOD question they''ve gotten less flames & more useful dicussion has ensued- so keep ''em coming!

...
There''s a small group of us here that believe OOD is the way, and I think we have convinced the other guys to ''just leave the crazy ones alone''

Magmai Kai Holmlor
- The disgruntled & disillusioned


#7 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 06 December 2000 - 07:39 PM

Just noticed the timing of this thread. Check out the design patterns section I just put on GDNet tonight: http://www.gamedev.net/gdpatterns.

Kevin

#8 Remnant   Members   -  Reputation: 122

Like
Likes
Like

Posted 06 December 2000 - 08:07 PM


thanks for the replies. I can see that it would be no problem ditching the owner pointer I''ve been keeping internally and just passing it in; even for a 5000-called-per-second routine, 1 more push onto the stack per, is negligable. My previous method of getting the parts to produce what they need is far more clunky than what you outlined there, Si.

Magmai,
I''ve thought of using decorators before, but the problem, as I see it, is that they''re a tough fit for my code. For example, a player might find a cloaking unit somewhere and install it onto their ship; there''s no clean method that I know of to replace the current instance of the ship (and all the pointers to it), with the new, decorated copy.

Also, I remember reading an interesting post on usenet a while back regarding OO choices. It was talking about OO in the realm of RPGs, and the interesting distinction it made was how an actor should NOT be subclassed by way of profession; because of this exact problem, a profession (or special ability in my case) can change at any time.

Example :

Character X is-a human. X currently works as-a peasant. X can go to school and become a mason, and gain all the abilities that that entails. Then X could move on and become a warrior, changing abilities yet again. Throughout all this though, X is still the same person, just with different skills.

This is a problem because a naive class hierarchy would look like:

Object -> Mobile -> Player -> Player_Peasant
Player -> Player_Mason
Player -> Player_Warrior

however this doesn''t allow for a human changing jobs, nor for having multiple professions at once. (nor, in my case, for having multiple special parts onboard). And of course, in this context, its clear that you may also want to have other Mobile-subclasses take on those professions; you probably will want NPC_Warriors and NPC_Peasants, for example.

This pops up in all sorts of other places too, sometimes where I barely recognize that its the same design problem.

I don''t want to get sidetracked about if the last example is best for writing RPG classes or not, but it DOES help exposese the problem I''m talking about from a different angle. Sometimes that helps percolate new ways to address the problem..

- Remnant
- (Steve Schmitt)


#9 Stoffel   Members   -  Reputation: 250

Like
Likes
Like

Posted 07 December 2000 - 04:24 AM

I borrowed design patterns from my company library and returned it just recently, so I don''t have it on hand. From that, I think the "Visitor" pattern also might work.

Your ship would have a list of components that are all "visitable". That is, they each inherit the interface "acceptVisitor (Visitor& v)". The ship on each update creates a Visitor object, whose purpose is to collect information about the components'' actions for that tick. It iterates through the list and passes this Visitor object to each component''s acceptVisitor method. The component can then tell the visitor object what it''s doing. Once it''s done with the list, maybe the Visitor has the new calculated bearing, velocity, ship state, whatever, and then the ship can act on that.

Design Patterns tells it better. You can also have multiple types of visitors for different types of algorithms or actions. It''s pretty neat. I gotta buy that book for myself.

#10 Houdini   Members   -  Reputation: 266

Like
Likes
Like

Posted 07 December 2000 - 05:57 AM

Wow, I love the idea of having a design patterns section that we can all add to. It''ll help a lot of people out tremdously. I only wish that the patterns all had examples, as examples make it much easier to understand how to apply the pattern.


- Houdini

#11 SiCrane   Moderators   -  Reputation: 9673

Like
Likes
Like

Posted 07 December 2000 - 07:57 PM

Well, when you come to the cloaked ship issue, there are a couple of ways to approach it. The first is to say that a cloaked ship is a special kind of ship. Another is to say a cloaked ship is a ship that has a cloaking device. So the choice becomes encapsulate or inherit.

If we go with the is a relation ship then we can create class Ship; and class CloakableShip : public Ship; This makes sense if in this particular universe cloaking depends on having more than just a cloaking device, it requires special hull materials, power systems, etc. In this case we don''t worry about non-cloakable ships become cloakable, and the is a relationship holds true.

On the downside: But then, what if StarBases can be cloakable too? The we have class StarBase; and class CloakableStarBase : public StarBase; Or we can go with multiple inheritence and CloakableShip inherits from class Cloakable and class Ship. Ugly ugly ugly. Let''s pretend we never had that thought.

Another thought is that cloaking devices still suck down power, don''t they? (At least I would imagine they would.) So we might end up creating cloaking device components anyway, for purposes of damage control, power consumption, etc.

For the real downer, let''s consider what if we created a ship that suddenly became cloakable? If we lived in the Star Trek universe, for example, there are numeruous examples of this happening. True we could try replacing the Ship object with a new CloakableShip object, but updating pointers can be a major headache. So instead we''ll declare that there''s only one class that can actually use pointers to Ship objects (outside of components of the Ship object). So we create the new ShipManager class. Ship manager handles the creation and deletion of Ship objects, and any other class needs to use handles in order to access Ship objects. So let''s create the ShipHandle class. Assuming for simplicity that there is only one ShipManager object (and we have a global pointer or something similarly easy to access it), we can implement ShipManager as a hash table or vector or something similarly quick to query, and that vector will hold the actual pointer to the class. Then the ShipHandle only needs to maintain an index into the hash table or vector. So now when we change a Ship into a CloakableShip, we create a new CloakableShip with all the same attributes as the old Ship, and replace the pointer in the vector with the new pointer. Because everything on the outside only uses handles in order to access Ship objects, the change is transparent to everyone on the outside.

And now for the real real downer. What if Cloakable wasn''t the only really special ship attribute? Then we get weird stuff like CloakbleInvulnerableShip and InsubstantialInertialessShip and CloakableInvulnerableInsubstantialInertiallessShip. Either you''ve got multiple inheritence ugliness on a truly unprecedented scale, or you''ve got a lot of cutting and pasting to do.

So now what if we consider a cloakable Ship as a Ship that has a cloaking device. Now making a non-cloaked ship a cloaked ship is as easy as swapping out a component. And also as a separate component, you can do things to the cloaking system just as you would other components. Swap them with other ships, damage them, etc.

We still have the downside of image rendering problems. One thought is that maybe cloaking is important enough or common enough that we just make cloaking part of every ship, and take that into effect when we do our drawing effects. i.e. every Ship when drawing will poll an isCloaked variable.

Another possibility is using function objects for your drawing functions. Let''s say that a Ship object has two special member variables. The first is DrawingFunction * m_pDefaultDrawingFunction. The second is DrawingFunction * m_pEffectiveDrawingFunction. So at the top of your Act() call for the ship, set m_pEffectiveDrawingFunction to m_pDefaultDrawingFunction (or a copy). This represents how the ship will draw itself without any weird effects. Then when different components get Act() called they might change the m_pEffectiveDrawingFunction variable. A cloaking device might use the old m_pEffectiveDrawingFunction object and set the alpha blending to near max. Or the ships engines if severly damaged might replace the drawing function with a function object that calls the old drawing funciton as well as drawing sparks near the engine. Of course this kind of thing introduces some downsides. After all, those function objects are going to create all sorts of vtables and extra pointers, which will eat up space and cycles as they get dereferenced.

Actually there''s a third choice: combine the two (a.k.a. chicken out). Make every ship cloakable, and whether or not it has a cloaking device determines it''s cloakability.

This is different from the first case because you''ve enabled any ship to become cloakable, and to some degree added cloaking overhead to the logic and drawing methods of every ship. Maybe before only CloakbleShips had the m_pCloakingDevice member variable, and now all ships will have this variable, so the non-cloaking ships take up a little more memory.

This is different from the second case, because in the second case, we actually put all the cloaking logic into the component,and for the most part is less flexible overall than the encapsulation method.

However, because something like cloaking is so involved, many times it''s implemented like this. This doesn''t prevent you from using the other methods for different components.

#12 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 07 December 2000 - 10:50 PM

I think the second is the way to go, since it allows you great flexibility in adding new types of components.

#13 Khawk   Senior Staff   -  Reputation: 1362

Like
Likes
Like

Posted 08 December 2000 - 07:46 AM

quote:
Original post by Houdini

Wow, I love the idea of having a design patterns section that we can all add to. It''ll help a lot of people out tremdously. I only wish that the patterns all had examples, as examples make it much easier to understand how to apply the pattern.


- Houdini



Well, one of the things I''m leaving open for the design patterns section is that people can make additions to existing patterns. Like if you have an example of the Spatial Index pattern and submitted it to me, I''d modify the pattern and give the modification a reference to you. This way the patterns aren''t set in stone.

Plus, I''m always looking for people to submit new patterns! (hint, hint)

Kevin



#14 Kylotan   Moderators   -  Reputation: 3338

Like
Likes
Like

Posted 08 December 2000 - 01:44 PM

Yeah, some good ideas thrown about here. Of course, there is no ''right'' answer.

I have something similar implemented in my MUD: a character can have any number of spells cast upon them, and each spell might have any number of given effects. So, some basic pseudocode for checking a character''s Strength might look like this:

currentStrength = basic character Strength
For all Spells cast upon that character
For all Effects within this spell
If Effect.type == Strength
currentStrength += Effect.Magnitude
return currentStrength


Now, that might seem pretty trivial, and may not even seem relevant, but if you substitute "Character" for "Ship", "Spell" for "Component", you may see how it could work. The example above works for boolean variables (eg. "Presence of cloaking device") as well as integers too. Just start with the default of 0 (no such ability) and the ''effects'' that give that ability will use 1 for their magnitude. The final result will be 0 (ability not present) or greater than 0 (ability present). This is all achieved simply by containing a list of Effects within the Spell/ShipComponent class, which are themselves in a list within the Character/Ship class. It allows any number of parts to co-exist, be added, modified or removed, at runtime.

However, this system represents ''properties''. It doesn''t actually do anything. For example, a single function call can query all components and tells you whether you have a cloaking device or not, but how to implement the graphic for that is external to the system. Personally, I think this is the way to go: the Ship class should be responsible for taking actions, it just collects information from its components beforehand. If you allowed the Components to directly modify the members of Ship, then you might have to start tracking the order in which it happened, or you might have to maintain reference counts, etc etc. (eg. Component 1 contains a Cloaking Device. Component 2 also contains a Cloaking Device. When you install Component 1, it changes Ship.Graphic to "CloakedShip" or whatever. Component 2, when installed, would do the same. But then, what happens when you remove one of those Components? Will removing Component 1 set Ship.Graphic to "UncloakedShip" since it was the Component that added the Cloak? etc) So I would prefer to just do:

if (GetFeature(CLOAKING_DEVICE) > 0)
graphic = "cloaked.pcx";
else
graphic = "uncloaked.pcx";

Similarly, code such as:
velocity += GetFeature(ENGINE_POWER);
can work for much of the design.

The only feature you mentioned that I can''t see how to easily and cleanly represent this way is "an autonomous turret needs targeting information from the ship''s sensors". I would probably model it something like this:

numSensors = GetFeature(SENSOR);
if (numSensors > 0 && GetFeature(AUTO_TURRET > 0)
OperateTurrents(numSensors); // A member of Ship

That example is almost certainly too simplistic for what you are doing, but hopefully you can see what I mean.


#15 Remnant   Members   -  Reputation: 122

Like
Likes
Like

Posted 08 December 2000 - 02:13 PM

wow, that''s a very exhaustive list of options there, Crane.

For my game, only the last option "Ship has-a cloaking device" really would work properly, for the reason you stated - ships can load/offload parts to give them different attributes and special abilities, with only a few restrictions (ie, perhaps the ship has to have Tech Lvl4 hull design to use a cloaking device, but any ship can use a reactive-armor type device, or afterburners -- you get the idea).

So the option that I want to go with is #2 (has-a cloaking device).. I think what I''m going to do is look into ways of doing as you said, and having a generic Ship have several different functions that allow the special-ability parts to change looks/behavior of the ship.

- Remnant
- (Steve Schmitt)


#16 JSwing   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 December 2000 - 12:11 AM

quote:
Original post by Kylotan

Yeah, some good ideas thrown about here. Of course, there is no 'right' answer.

currentStrength = basic character Strength
For all Spells cast upon that character
For all Effects within this spell
If Effect.type == Strength
currentStrength += Effect.Magnitude
return currentStrength



Might this be better if you abstract the different spell types from a common root rather than having a flag for each effect? You could decouple the spells from the character, which would allow the internal implementations to be hidden. Like:


Character:
basicStr, currentStr
Character()
{ currentStr = basicStr }
increaseStr(amount)
{ currentStr += amount }
list spellsOnMe
bool addToSpellsOnMe (refSpell)
{ if (spellAlreadyOnMe() and not refSpell->isCumulative)
return (FALSE)
else spellsOnMe += refSpell
return TRUE
}


Spell:
virtual castMe(target)
bool isCumulative
virtual failureMessage()
{ "Spell failed" }


StrSpell : Spell
magnitude
castMe(target)
{ if target.addToSpellsOnMe(this)
target.increaseStr(magnitude)
else failureMessage() }



Now the character only needs to understand the basic spell interface, and the spell only needs to know the basic character interface. The details remain isolated, while the important functions are available for other objects to use.

You could modify and expand this, of course, to include a wearing off function, but you basically refactor the design into something more flexible.

As you said, there is no right way of doing things. This is just another option.

Edited by - JSwing on December 12, 2000 8:55:36 AM

#17 Kylotan   Moderators   -  Reputation: 3338

Like
Likes
Like

Posted 12 December 2000 - 12:41 AM

I must admit slight ignorance in that I can''t really see what you''re trying to tell me. Perhaps because we''re thinking along very different lines.

I don''t want a class for each spell, as this system doesn''t just have to model spells. It can model any effect. For example, a Drunkenness effect might modify Awareness by -10% and Agility by -20%.

You might then just say "well, have a class for any effect then", but that still isn''t useful/necessary. There are times when I want to generate a new effect, at run time. To go into more technical, the system doesn''t have ''spells'' on a character. A spell is an object that, as part of it''s execution, may attach an Effect object to that character. An Effect object is essentially a list of Modifier objects. A Modifier object is an attribute/value pair, such as {"Awareness", "-10"} from the example above. My example in a previous post uses different terms as I was just trying to be abstract.

Here''s the actual code I use:
  
int Character::GetTotalModifiersTo(String stat) const
{
// Loop through all effects. If the stat matches this one, apply the

// difference to the running total. Return the final amount

int total_modifier = 0;
EffectList::const_iterator eli;
for (eli = effects.begin(); eli != effects.end(); ++eli)
total_modifier += (*eli)->GetModifiersTo(stat);
return total_modifier;
}

The Character loops through its Effects, and asks them in turn if they have any modifiers to the specified statistic. Obviously, the Effect object then loops through its own Modifier objects, totalling up anything for the given stat. In the end, the result is returned and total_modifier will get altered accordingly. The Character class doesn''t need any knowledge about spells or skills or drunkenness: all it needs to know is how to call the GetModifiersTo(stat) function. Similarly, skills and spells etc don''t need to know much about Characters: they just need to be able to generate an Effect object and attach it to the specified character.

Technically, I can even add new statistics at run-time within this system, as the statistic type to be queried can be specified with a string.

Does that address your points? Is there any other way I could improve this?

#18 JSwing   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 December 2000 - 02:23 AM

Fixed my post so it indents ok.

Actually we''re approaching it from different sides. I think we''ve each got different pieces of the same elephant.

You''ve got a composite pattern for the effects, which is (IMO) great. I threw in a generic list instead, but your construction is better.

I was approaching it from the effect side, where the effect changes the player attribute when invoked (more like a visitor pattern). You approach it from the character side, where the character calls for the effect when needed. (Replace ''spell'' in my example with ''effect'')

With your routine every effect has to know how to deal with every stat, which may not be a big deal. With my version, if the character interface changes (the addToStr function) then the effects break.

I think either would work. (In fact they could dovetail together). I guess it comes down to how often you will need to call your loop, which I think depends more on your game design than your code.



#19 bogdanontanu   Members   -  Reputation: 122

Like
Likes
Like

Posted 13 December 2000 - 10:25 AM

Hi

Take care with OOP in games...

OOP may be efficient for the programmers point of view ...but is
awensome slow so totaly ineficient for speed whatsoever...

A good game can be done with no OOP whatsoever...(besides menu systems) so use OOP wisely and only in no speed critical sections...

IMHO of course
Bogdan

#20 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 13 December 2000 - 11:41 AM

quote:
Original post by bogdanontanu

Hi

Take care with OOP in games...

OOP may be efficient for the programmers point of view ...but is
awensome slow so totaly ineficient for speed whatsoever...

A good game can be done with no OOP whatsoever...(besides menu systems) so use OOP wisely and only in no speed critical sections...

IMHO of course
Bogdan


I disagree.

People love to point out the fact that OOP is slow and inefficient.
This is their ONLY argument against OOP. People who use OOP, use
it wisely. They don''t use it blindly. Smart designers use profilers
to judge the performance of their program.

I know there are fast, commercial games out there on the market
that use OOP. Perhaps someone should create a list of these games
to kill off arguments like this once and for all.







Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS