🔒 Locked
Class or Struct...
Advertisement
Original Post
Neither.
No.
There will be no difference at all in a release build.
Magmai Kai Holmlor
"Oh, like you''ve never written buggy code" - Lee
"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO
No.
There will be no difference at all in a release build.
Magmai Kai Holmlor
"Oh, like you''ve never written buggy code" - Lee
"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO
AP 1: If the accessor functions are inlined, there''s no speed difference.
AP 2: v-tables == virtual method tables, and they only affect performance on virtual methods.
AP 3: I agree completely.
As for the difference between classes and structs -
If I want my data members to be private, I call it a class.
If I want my data members to be public, I call it a struct.
struct Vector2D {
float x, y;
float LengthSquared() { return x*x + y*y; }
};
AP 2: v-tables == virtual method tables, and they only affect performance on virtual methods.
AP 3: I agree completely.
As for the difference between classes and structs -
If I want my data members to be private, I call it a class.
If I want my data members to be public, I call it a struct.
struct Vector2D {
float x, y;
float LengthSquared() { return x*x + y*y; }
};
The AP is correct in saying that OOP is used to much by some people, but i disagree over using it rarly.
I''m not a fan of having your class inherit from CObject when CObject doesn''t do anything. DOing that just makes things convoluted. However there are many times where 2 otherwise unrelated classes should be inherited from a base. For example, i wrote a handful of classes to put a layer of OGL a while back. Material, Light, and Texture where a few. Each inherited from Storable. Storable had 2 pure virtual funcs,
ofstream & Write(ofstream & stm);
ifstream & Read(ifstream & stm);
each of the three classes implemented these two funtions. Otherwise, they were completely different.
I nolonger write code that isn''t in some object. I want to write some math funcs, they go in class Math. Everything that a computer can do can be put in classes to make it simpler, like an Asteroid game having a set of classes, like:
class Drawable
{
... saving, drawing, moving sprites here
}
class Asteroid : public Drawable
{
... pure virtual, and reg funcs here
}
class BigAsteroid : public Asteroid
{
... implement some funcs
}
class LittleAsteroid : public Asteroid
{
.. again
}
class Ship : public Drawable
{
... ship code
}
class Game
{
... the time, ship, asteroids, blah, blah
}
You can see that each of these classes represents something real and uses others funtions, like sprite handling, or asteroid movement. I have found that games are possibly the single best place for OOP, and i never suggest not using OOP because it might be slower, but like I said at the start, make sure you know WHY you are making classes inherit and so forth
RELIGION IS THE ROOT OF ALL EVIL
I''m not a fan of having your class inherit from CObject when CObject doesn''t do anything. DOing that just makes things convoluted. However there are many times where 2 otherwise unrelated classes should be inherited from a base. For example, i wrote a handful of classes to put a layer of OGL a while back. Material, Light, and Texture where a few. Each inherited from Storable. Storable had 2 pure virtual funcs,
ofstream & Write(ofstream & stm);
ifstream & Read(ifstream & stm);
each of the three classes implemented these two funtions. Otherwise, they were completely different.
I nolonger write code that isn''t in some object. I want to write some math funcs, they go in class Math. Everything that a computer can do can be put in classes to make it simpler, like an Asteroid game having a set of classes, like:
class Drawable
{
... saving, drawing, moving sprites here
}
class Asteroid : public Drawable
{
... pure virtual, and reg funcs here
}
class BigAsteroid : public Asteroid
{
... implement some funcs
}
class LittleAsteroid : public Asteroid
{
.. again
}
class Ship : public Drawable
{
... ship code
}
class Game
{
... the time, ship, asteroids, blah, blah
}
You can see that each of these classes represents something real and uses others funtions, like sprite handling, or asteroid movement. I have found that games are possibly the single best place for OOP, and i never suggest not using OOP because it might be slower, but like I said at the start, make sure you know WHY you are making classes inherit and so forth
RELIGION IS THE ROOT OF ALL EVIL
My comments:
1)If you don''t understand some of the things that have been asked in this thread, then COMPLETELY forget about speed for the time being and concentrate on how things work and why. After you have a good idea of that, you''ll be in a better position to ask about such trivial performance gains.
2)All MFC classes derive (directly or indirectly) from a CObject base class (almost all of them at least). The CObject class provides serialization, run-time class info, diagnostic output and compatibility with the Microsoft collection classes. Granted, you could achieve those results using 4 different base interfaces and inherit from all of them, but there''s nothing wrong really with this method. If ALL of your objects are going to need a core functionality, roll that into one object and go from there. It just makes things easier.
1)If you don''t understand some of the things that have been asked in this thread, then COMPLETELY forget about speed for the time being and concentrate on how things work and why. After you have a good idea of that, you''ll be in a better position to ask about such trivial performance gains.
2)All MFC classes derive (directly or indirectly) from a CObject base class (almost all of them at least). The CObject class provides serialization, run-time class info, diagnostic output and compatibility with the Microsoft collection classes. Granted, you could achieve those results using 4 different base interfaces and inherit from all of them, but there''s nothing wrong really with this method. If ALL of your objects are going to need a core functionality, roll that into one object and go from there. It just makes things easier.
Accessing virtual functions has a run-time cost of one pointer dereference per call when compared to non-virtual functions. Also, there is a single pointer tacked on to the end of each class involved with inheritence to point to its static (one per executable) vtable, plus the static allocation of the vtable itself. (There is also the cost of a tight dependence of the derived classes to base classes--they must be #included in the header, meaning all clients must know about all classes up the tree to the base.)
This is a "cost" when compared to non-virtual functions, but the most common problem virtual functions solve is that of eliminating a "type" member and switch (type) trees. When you compare these two solutions, inheritence is a more maintainable & extensible solution that has nearly the same overhead as the alternative. However, because of the dependence cost mentioned above, it should only be used in situations where it's useful (sounds like a truism, but how many times have you seen the opposite?)
The best advice I've ever heard is this:
"Never use inheritence to share code (use composition instead);
only use inheritence if you are going to treat a derived class as base class."
Edited by - Stoffel on December 24, 2001 1:58:09 PM
This is a "cost" when compared to non-virtual functions, but the most common problem virtual functions solve is that of eliminating a "type" member and switch (type) trees. When you compare these two solutions, inheritence is a more maintainable & extensible solution that has nearly the same overhead as the alternative. However, because of the dependence cost mentioned above, it should only be used in situations where it's useful (sounds like a truism, but how many times have you seen the opposite?)
The best advice I've ever heard is this:
"Never use inheritence to share code (use composition instead);
only use inheritence if you are going to treat a derived class as base class."
Edited by - Stoffel on December 24, 2001 1:58:09 PM
quote:
Original post by Anonymous Poster
I don't know that much MFC so some of what I say will be wrong. CObject is just a really bad name. Aren't all MFC things interface components?
Aside from interface objects, MFC also has things like CArchive, CArray, CDocument, CWinApp, CHttpConnection, COleObjectFactory, CMutex, etc. Interface objects only account for about half of MFC's classes (eyeballing the heirarchy chart).
CObject gives you public functions for diagnostics, serialization (optional) and RTTI/class factory functions (also optional). Basically, CObjects are things that can have diagnostics run on them, that can optionally be serialized and created dynamically.
There is also a space on the heirarchy chart for "Classes Not Derived from CObject", so not all MFC classes derive from CObject.
Edited by - Stoffel on December 26, 2001 1:51:17 PM
AP:
You method is a very good and valid way to organize functionality. I haven''t read Design Patterns, but small chunks that move is good. However it is somewhat useless to really discuss the design of Asteroid, seeing as there are so many valid ways to do it, and that the point i want to make to the intial poster. How you code is really a matter of taste, especially for beginners doing it for a hobby, as they have just about no one to try and interpret there code. I have found that the best way for me to start getting classes, a hierachy, and functional relationships started is to sit down, delineate the goals and existing systems to tie in and just start thinking. You need an UserInterface class? A list of currently held keys? just continue in this fashion until the design starts forming, and chances are, the design will work. Then just elaborate more and more, until you type some letters on your editor and BINGO you have a game. (Gross simplification). My advise to the poster is to do this and come up with a good design of classes that HE/SHE can fully understand and is clear to him/her.
He who said money was the root of all evil knew little of the nature of money and less about the nature of man.
You method is a very good and valid way to organize functionality. I haven''t read Design Patterns, but small chunks that move is good. However it is somewhat useless to really discuss the design of Asteroid, seeing as there are so many valid ways to do it, and that the point i want to make to the intial poster. How you code is really a matter of taste, especially for beginners doing it for a hobby, as they have just about no one to try and interpret there code. I have found that the best way for me to start getting classes, a hierachy, and functional relationships started is to sit down, delineate the goals and existing systems to tie in and just start thinking. You need an UserInterface class? A list of currently held keys? just continue in this fashion until the design starts forming, and chances are, the design will work. Then just elaborate more and more, until you type some letters on your editor and BINGO you have a game. (Gross simplification). My advise to the poster is to do this and come up with a good design of classes that HE/SHE can fully understand and is clear to him/her.
He who said money was the root of all evil knew little of the nature of money and less about the nature of man.
Ok, I have this POLYGON2D class that basically has position, velocity and bounding variables, and a few methods to draw, rotate and scale, etc. In my asteroids clone, would it be smart for all the game objects to inherit it, so they can use all those base methods, and yet add a few more specific to themselves? Is that good?
...go on and live with no regrets, you only have one life...
...go on and live with no regrets, you only have one life...
quote:
I don''t know your situation but I probably would have just overloaded the stream operators instead of writing Read and Write functions
Bad idea if you ever treat a derived class as its base class, like so:
Monster *monster = new Ogre;
When you try to stream that out the stream function for the Monster object will be called, thus it won''t print out Ogre specific values. If you make those stream functions call a virtual function in Monster (like Write), and that is overriden for all new derived classes, then the proper function will be called at runtime.
quote:
"Never use inheritence to share code (use composition instead);
only use inheritence if you are going to treat a derived class as base class."
I don''t think I agree with that. You should use inheritance for is-a relationships and composition for has-a relationships or for is-a relationships that aren''t permanent "
If you use composition for is-a relationships then you are trying to force something to fit that should fit naturally, and vice-versa.
For instance, the big "knock" on inheritance compared to composition is that if you make a change to the base class, it ripples down and effects all the subclasses. This is the whole reason to use inheritance for is-a relationships, because this is exactly what you want.
quote:
I know your example is just an example but I think you are using inheritance too much. Instead of a class Drawable have your asteroids own an instance of Drawable.
I may agree with this if there are times when an asteroid shouldn''t be drawable, say on game servers.
Of course, I don''t agree at all with objects being able to draw themselves (as logical as it sounds) because this makes it harder to optimize drawing by sorting everything by texture or model.
quote:
Instead of having big and small asteroids be seperate classes make one or more variables dealing with size.
Agreed, you don''t want to go overboard with inheritance (or with composition, for that matter).
quote:
Likewise Ship and Asteroid don''t need to be seperate classes either. They both need instances of Drawable and/or Collidable (you could merge them if you want). The Ship and Asteroid can merge into one class
I think it''s a bad idea to merge two classes just because they are mostly similar. Mixing them means you end up with a bunch of variables that never get used for each single instance of that class you create.
quote:
then to give them seperate behavior have them both controlled by objects of different classes. That''s where you throw the inheritance in.
I''m a bit confused here. Are you saying create one Entity class that contains every possible variable for all possible entities, then create seperate AstroidBehavior, ShipBehavior, etc, classes that access this huge Entity class?
- Houdini
quote:
Original post by untalkative_monkey
Ok, I have this POLYGON2D class that basically has position, velocity and bounding variables, and a few methods to draw, rotate and scale, etc. In my asteroids clone, would it be smart for all the game objects to inherit it, so they can use all those base methods, and yet add a few more specific to themselves? Is that good?
...go on and live with no regrets, you only have one life...
Sounds like you''re on the right track. Some people might debate about different ways to decompose the game into different objects/classes, but if you''re new to OOD don''t worry about what is nescessarilly the "best" way. Get used to the concepts and get some practice. Just don''t over do it and make a new class for every single entity.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement