Advertisement

How to use C++ Properly

Started by April 12, 2000 06:44 AM
15 comments, last by Kosh 24 years, 7 months ago
I'm not sure I agree with daveb, it would depend on what one want's to accomplish, and how you went about it. Inhereted classes should not be any slower to code or execute, unless you're creating and destroying massive amounts of points in which case the calls to the constructors/destructors may have some effect.

An initialization list is a way of initializing base class variables and derived class variables:

Assuming x, y, and z are in the derived class, and color is in the base class, this constructor uses the init list to initialize only the base class, and initializes the variables in the function itself:

int C3DPoint::C3DPoint(int init_x=0, int init_y=0, int init_z=0, int init_color=0) : CPoint(init_color)
{
x = init_x;
y = init_y;
z = init_z;
}

This one uses the init list to initialize everything:

int C3DPoint::C3DPoint(int init_x=0, int init_y=0, int init_z=0, int init_color=0) : CPoint(init_color), x(init_x), y(init_y), z(init_z)
{
// nothing here, everything's done already
}

Note: if you need to to mem allocation, etc, don't do it in the init list.

Brian

Edited by - An Irritable Gent on 4/12/00 3:41:53 PM
aig
Inhereting C3DPoint and C2DPoint from CPoint would allow polymorphism, something you won''t get if you avoid inheritence. It could be very useful, depending on what you''re doing, to treat both C2DPoints and C3DPoints as CPoints for loop iterations, arrays, etc.

But I would avoid deriving C3DPoint from C2DPoint, implying a 3D point is just a 2D point with an extra coordinate. To me, that''s like saying a Piano is a Guitar with extra strings, or a Car is a Motorcycle with extra wheels. Instead, create a base (Instrument, Vehicle, Point) and derive things from that (Guitar & Piano, Car and Motorcycle, 2D and 3D), and let each derived class worry about its own strings, wheels, and coordinates. Things common (and non-extendable) to derived classes could be put in the base class, such as instrument_value, vehicle_weight, and point_color.

Another reason a 3D point shouldn''t be derived from a 2D point is this: which should you do - derive a 4D point from a 1D point, a 2D point or a 3D point? You could derive from a 1D point and just add 3 coordinates, or derive from 2D point and just add 2 coordinates, or derive from a 3D and add one - makes no difference, and will lead to confusion because it''s not the natural way of thinking about it - at least for me! ;-)

Brian
aig
Advertisement
quote: Original post by An Irritable Gent
Inhereted classes should not be any slower to code or execute, unless you''re creating and destroying massive amounts of points in which case the calls to the constructors/destructors may have some effect.


There''s an overhead you''re not seeing here. You''re taking something fundamentally simple and gumming it up with an inheritance chain, taking the simple functionality of three lines of code and spreading it out among various classes and constructors. Simpler is almost often better when it comes to programming. Just that there has to be a thread about how to define a point should be the tip off that something isn''t right here.

I agree there''s a trade off for something as simple as grouping and initializing 3 integers. But then again even complex problems don''t require anything more than structs and global functions - sort of a matter of organizating and personal preference I guess. Also, it depends on what you''re trying to accomplish, and how/if you''ll want to expand/modify it later. Although I see your point. I certainly wouldn''t create a base class "Number" and then derived classes "Integer", "Float", etc just to use integers and floats. ;-) If you''re positive all you want is 2D points and/or 3D points, and only their coordinates and nothing else, ever, it''s a toss up in my opinion.

I guess "simpler" should take into account "simpler to modify or expand in the future" as well. ;-)

Brian
aig
I guess I'll add my 2 cents to the discussion. *group groans*. As some other people have said, it depends on what you are doing. If you want both classes to act like a point, then you will most definitely be defining virtual functions in the base class (in this case it would be a point). Perhaps what you would be defining would be operators? It would make sense to add, subtract, multiply, or divide a 3D point by a 2D point, or even just an int. That would have the effect of scaling, etc.

If you are not using virtual functions in your class (operators are functions), then you might as well forget the hierarchy. It won't be of any real use, and I think that is what most people were saying. A class with little data should be small and fast, because they are often used quite often in large arrays or lists.



Some advice on OOP:

OOP is like "functional design," or "form follows function." If it doesn't work right or you are repeating code, then there is a flaw in your design. Likewise, if the class is too large to do its job correctly, then there is a flaw in its design. Live by that rule, learn the ins and outs of C++, and you'll write good code. Remember: far too many people do not have any idea of the power and flexibility in C++ and thus their implementations are slow and clunky. Never try to force C-style code into classes -- rather, you adapt the code to the classes.

People never think perfectly; their view of reality is always altered (however slightly it may be) by their viewpoint. (3D programmers should know this better than anyone -- just think of all the coordinate systems you have to use to model a 3D world!) The goal is to match your viewpoint to reality. C++ demands a realistic viewpoint to produce small, fast code. When you are not understanding something according to your viewpoint, you must ask someone who knows and correct it. Bad programming comes from bad thinking (or simply not-knowing, but that's not what I'm talking about here).

So, when someone says, "That is not the way I think," and you are showing them how it must be coded for speed and efficiency, they are in fact telling you, "I do not think correctly." The human brain naturally uses polymorphism, abstraction, classes, etc. so what they are doing is putting their own style of thinking in-between their brains and the data they are trying to process. That is why it comes out so "muddled" and requires much more code to do the same thing. If something is simply not fitting, either you don't know enough about what you are trying to do, or you have it modeled incorrectly. There are far more examples of bad design on the Internet than examples of good design.


All this came from the theory: "Good C++ code is small, fast, and easy to read."

The common misconception is: "Good C++ code is either small, fast, or easy to read."


An Irritable Gent: Actually, you hit upon the exact way in which compilers think about numbers. They make a generic, data-less class, like "class Number {};", and then derive all the different types of numbers from it. It's only a concept -- no actual code, but it is very logical. Also the same for pure virtual functions. Your brain always makes some type of abstract type for similar objects. It would be the best structure, because say they made some other intrinsic types, like "class Pointer {};". Now, the don't need to know the type of the class, other than it is a pointer. That means that, to do type-checking by differentiating between a pointer and a number, they don't have to handle 20 or 30 different cases for int, float, char, double, long, short, int*, float*, etc. Adding a new number or pointer type is also a snap, as it doesn't involve changing mammoth switch() statements in the compiler code. Simple type-checking like this is an excellent way to eliminate code.



- null_pointer
Sabre Multimedia


Edited by - null_pointer on 4/12/00 2:21:49 PM
null_pointer, good comments about modelling. However, I wonder about this - since computers and computer languages are part of the real world as well, programmers (especially ones doing it for a long time) start to think of things in terms of their language - in other words, for old-timer C coders it may be just as much abstraction in thinking of a "struct" (or other compiler ''object'') as thinking of a "point" (or other real-world ''object''). Like arriving at the point where you naturally consider your cable-TV stations an array of integers or your geneaolgy as a binary tree. ;-) Somewhere there''s a line where ''abstraction'' is crossed, but I think *sometimes*, especially in small examples like a 2D or 3D point, that line can get blurry. ;-) What cha think?

Interesting comments on the compiler''s view of numbers.

Brian
aig
Advertisement
An Irritable Gent: Hmm...perhaps... I never quite thought of it that way before, but still the language is bad and it takes a longer time to learn (easy to learn, much harder to condition the brain that way). Because of the difference in the coding style and the thinking of the brain with C, most C programmers carry over "had habits" that would be okay with C but don''t fit the coding style of C++. For example, they use switch() statements where simple type-checking will do, re-write similar classes entirely where a little hierarchy would make things much easier to understand, etc.

C++ may use much (if not all) of C''s syntax, but the changes are enough to make it a completely different coding style. A while ago, I tried to look at C source and write some myself, but it took me half an hour (yes, half an hour) of writing and erasing code before it clicked and I realized how to write it as if I were writing an object. I must tell you, it''s a clunky format to write objects in. No virtual functions, no hierarchy, etc. C is just further from how the brain actually thinks. If you can code procedural code that''s great, but it''s easier (and faster)
(and less error-prone) to develop in OOP (when done correctly). The really hard part is watching C coders, who programmed for months or even years in C, try to learn C++ in a few hours and denounce it as a horrible language.
C++ is a whole different style of thinking, and that''s why many people call it a whole different language.




- null_pointer
Sabre Multimedia

This topic is closed to new replies.

Advertisement