• Advertisement

Archived

This topic is now archived and is closed to further replies.

How to use C++ Properly

This topic is 6522 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi everyone, I would like to know, I have this little problem and I am not too sure on how to get around it. if I have a class, say Point, defined like this class Point2D{ private: int x, y; public: Point2D(){ x=0; y=0} ~Point2D(){} }; and then I want to extend it, so that I can have a 3D point, now, I want to make a Point3D class yeah, so how would I extend this class to do so ? like this perhaps ? class Point3D: public Point2D{ private: int z; public Point3D(){ x=0; y=0; z=0;} ~Point3D(); } if this is correct, I now have one problem with this. its that x and y are now public, they are not private, so now, functions or methods external to the class have access to x and y, but not z, but I dont want that, so you might say to put private Point2D where I define the point3d class, but then I would get everything in private, but what about public stuff thats in Point2D ? it''s not been made private, so now anything outside the class cannot access the extended Point2D stuff, cause of this rule. my question therefore, at last, is how can I do this, keeping public things public and private things private ? is there a way to do this is this even a problem, if not, explain what should I do in this situation cause what I wanna do is better done another way thanks for your help kosh

Share this post


Link to post
Share on other sites
Advertisement
Hi,
If the base class has members defined as private then they are only ever accessible from the base class, regardless of the access level specified for the inheritance. So x & y will not be public but also will not be accessible through Point3D.

Use the ''protected'' access specifier for x & y and derive Point3D from Point2D using ''public'', these will then be accessible through a Point2D or Point3D object. If you are not going to derive from Point3D then z can remain private.

ie.

class Point2D{
protected:
int x, y;
public:
Point2D(){ x=0; y=0}
~Point2D(){}
};

class Point3D: public Point2D{
private:
int z;
public
Point3D(){ x=0; y=0; z=0;}
~Point3D();
}

Hope this helps,

Niv

Share this post


Link to post
Share on other sites
If you are going to inherit from a base class and you wish to keep data hiding. Use protected members they act in the same way as a private member, but the derived class can access them. While maintaing data hiding. So in your 2D point class,

int x, y; would be accesable by your 3D point class, but would not be accesable by any extenal methods or functions.

Share this post


Link to post
Share on other sites
quote:
Original post by Kosh

like this perhaps ?

class Point3D: public Point2D{



I think your confusion comes from the "public Point2D" part. Public inheritance doesn't mean that all your private variables become public, thankfully It just means that your public variables stay public in the derived class, rather than defaulting to private.

Also, if you want maximum efficiency, you should probably use initialisation lists rather than assignments for setting up the x,y,z values in the constructor. Eg:
Point2D:: Point2D : x(0), y(0) {}
You shouldn't need to initialise x and y in Point3D either, as they will take Point2D's constructor I believe.

Edited by - Kylotan on 4/12/00 9:29:16 AM

Share this post


Link to post
Share on other sites
Hi !!

Well, OOP is great, but I think you shouldn''t really put it to it''s limits.

I mean, create two classes that are independant:
C2DPoint and C3DPoint.

There is really no need to derive a 3D Point from a 2D Point.

That''s my opinion.

Phillip

Share this post


Link to post
Share on other sites
I really agree with Philip on this one. Oop is so much more then inheritance. I see people use inheritance for way too much things where there are better solutions. I tend to avoid implementation inheritance all together and stick to interface inheritance only.

But i''m sorry. That wasn''t the topic .

On a side note:

can anybody explain initialisation lists to me?

thanks,

Jaap Suter



____________________________
Mmmm, I''ll have to think of one.

Share this post


Link to post
Share on other sites
Hi Phillip,

I was thinking the same thing. I would probably even make C2DPoint and C3DPoint each derived from a CPoint class, with the coordinates declared in the derived classes (or setting up a coordinate array pointer in the base class, which the derived classes allocate and free, so I could make 4D or 17D points if I wanted, but that''s probably an unneccessary complexity unless you''re doing some abstract advanced physics or something).

Deriving C3DPoint from C2DPoint doesn''t seem like the best idea from the organizational point of view, ''cause it''s kind of like saying a 3D point is a kind of 2D point - which can be explained but it''s not the most natural way of thinking about it.

Brian

Share this post


Link to post
Share on other sites
I would agree with s9801758 here. Using inheritance in this case is a classic example of how _not_ to use C++. You would in effect just be using C++ just because you could. In terms of low-level (or even mid-level) graphics stuff, I''ve found that hardcore C++ just has no place. You''ll end up wasting huge amounts of time. Why not just use

struct 2d_point {
int x, y;
};

struct 3d_point {
float x, y, z;
};

Its _way_ simpler. You might consider using a vector (x, y, z) class simply because you can do some nice operator overloading for addition/dot-product/etc. But using inheritance is massively overkill for something like this.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I "agree" with s9801758.
I would also like to know what an
init list is =)

Share this post


Link to post
Share on other sites
Hello Kosh

Well, I don''t know alot about c++ but read this anyway. May help you decide what to do.
One of the problems with new c++ developers is to use inheratence to much, to over use it. Some times it make the solution harder to get to.
So the question is why are you going with inheratence, are you taking functions from one to use with the other. If you have a 2d point with x and y, and a 3d point with x,y,z then for the 3d point you are not using any functions from the 3d point and may be better left apart.
If you want to use inheratence then put x,y in 2d with all the methods you need, and put just the z in the 3d point. Then any of the methods that need z, write them to be virtual so if you are using a 3d point it will know to use the methods for the 3d point class.
Later Ben
Your best bet is to create them seperate. Each class would be easier to maintain that way.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

  • Advertisement