Quick OOP question

Started by
21 comments, last by Turtlebread 22 years, 7 months ago
I was writing some classes when I came up with this question. Say I have a class with a member variable named a. Is it worth it for one to code a like this: class MyClass{ public: void setA(int value); int getA(); private: int a; } And then access "a" through the functions. Or should I just make a public and access it through MyClass.a? I guess this is an opinion question, but I''m wondering what people think. -Chris
Advertisement
Its really up to you.

The strict OOP guys will tell you its always best to use setters and getters in case you want to change how the class works and you want the setting of variable to kick off some other bit of code that you hadn''t forseen previously.. Abstracting the implementation and all that. In the real world, there''s plenty of cases where a variable is just a variable and you''ll never need to do that.

Unless you have to follow some coding guidelines for a job or for school, use whatever style you want... And, for the record, most sane compilers will optimize out the function call overhead by inlining if all the function is doing is setting a single variable based on a parameter, so in terms of run-time efficiency it doesn''t really matter which you use.
Convention decrees that if it has public data members, it is a struct. Classes should not have public data members.
the strict OOP guys do have a reason why you use getters and setters ... but they really only matter in 3 cases - the two cases when structs are inappropriate - here they are:

1. You want to impose restrictions on the values of the variable, or keep it''s changes synced with other values.
2. You want to perform some additional action when the value is changed or accessed.
3. You want to allow derived classes to change the behavior of the getters and setters.

Items 1 and 2 are really the key to deciding if you have a simple struct or if you are dealing with a more complex class. While it is acceptable to mix and match ... say have a class that has complex logic for 3 members and no logic for 2 other members ... it''s usually best to stay at the same level of abstraction ... presenting your users with a consistent interface.

Item 3 requires that you not only use getters and setters, but that you also declare them virtual ... but it should be fairly obvious when you want to do this.

NOTE: Using getters and setters can also allow for some simple debugging tricks ... like launching the debugger when a value is set to NULL .... or negative .. or whatever you don''t think you want to be doing.

Don''t try to avoid structs though ... they are immensly usefull for wrapping groups of data in easy to handle chunks - a struct with usefull constructors and/or operators can simplify your code a lot.

Good Luck
The key difference being, of course, that structs are passed around, and information usually ends up being hidden anyway. Don''t hardcode value changes...it''s going to crash on your head, especially if you need to substitute a different implementation later.
VK
it isn''t really that difficult of an issue, the answer is: make it public unless there is a reason to make it private. If there is a reason, any reason at all no matter how small, then make it private.

For example we want to make a vector class. We can do it several different ways. We can store the x and y, we can store the angle and magnitude, or we can store both sets of information and keep them synchronized. Which one you use varies on what you are doing, most people use the x,y but there are reasons you might want to consider using the other ones. Now this looks like an argument for getters and setters but it isn''t. I think we can assume that you''ll make a permanent decision on which type you are using early in the project. For the first two types you''ll want to make everything public, there is absolutely no reason to make anything private. For the second one we have to make things private. The reason is that if they change any variable two others are supposed to change with it. So if we change magnitude the angle will stay the same but the x and y will change, likewise if we change x both magnitude and angle will change. Thus everything must be private.

Basically if variable B is dependant on A, then A must be made private and if B is totally dependant on A then B must be private as well. Making things private and using setters is the best way to keep states consistant. In my experience the whole "freedom to change representation" argument is rather very very overrated but valid. Sometimes you''ll want to make something private so you can change it later, but I find it to be one of the rarer uses of private members. Oh and one last piece of advice: learn all about various programming paradigms but don''t make any attempt to follow them. When it is a given paradigm''s turn to shine it will leap to your fingertips and apply itself. If you have to force a paradigm out then you probably aren''t using the right one.

As to the whole struct vs class distinction that''s just terminology. As far as I know C++ treats them identically. I just always use the class keyword because I am used to java.
What I don''t understand is why you would bother hiding a variable by making it private, and then exposing it to the world by rpoviding getter/setter routines on it

--


Games, Anime and more at GKWorld

Meet Bunny luv'' and the girls, all ready to perform on your desktop just for you (warning: adult content).

My answer is to taliesin73, although it is also valuable to the original poster as well:

A class should have no public data and only access them through accessor functions, as each object needs to be able to know when its state is altered.

It''s a simple philosophy, and one that saves you a lot of time fixing up code later in development. As an example... imagine a Document class for a text editor, with a Text object inside. (It could be a string, or list of strings, whatever). You might let your program alter the Text member directly, to add, delete, or replace words.

Then, at some point, you decide you want to add a ''modified'' flag to a Document, so that the system knows whether it needs saving to disk or not. If you used public member access to modify ''Data'', then you have to find all those places in the other code, and add a line like ''Document.SetAsModified()'' everywhere. But if you''d used accessor methods to alter Text, you would only need to add ''SetAsModified()'' in those methods.

Another example of a side-effect you might want, is a timestamp to mark the last time that you changed the object. Or the ability to add the change to an ''Undo'' list so that the changes can easily be undone later.

By using getter and setter routines, you are funnelling all access to a variable through a well-defined piece of code. As long as all you''re doing is modifying the variable directly, the compiler will optimise most of this out. And as soon as you want to do something more complicated than simply change the data type, you know you only have a minimal number of places where you need to change the code.

(As if that wasn''t important enough, there are the other added benefits of data and functional abstraction, the ability for derived classes to override the base class''s getter/setter functions, and so on.)
Well, this is an opinion but I think that religiously making all members private and using Get() and Set() routines is not good programming. For something like a vector, where you are likely to want to reference the variables a lot, use of Get() and Set() are a pain in the arse. You should make your members private to get the "black box" effect - gratuitious use of Get() and Set() just leads to sloppy encapsulation, and overcomplicated, bloated classes.
quote:Original post by Sandman
Well, this is an opinion but I think that religiously making all members private and using Get() and Set() routines is not good programming.

I disagree on a technicality: using Get() and Set() to alter a variable is good programming, but making a class where it''s just a load of private variables with a Get and a Set for each one is a symptom of bad design. Rarely do all the variables in any single subsystem have to be exposed to the ''outside world''. Religiously making variables private is a good thing in terms of encapsulation, abstraction, and object-orientation. Adding a get and set for each one shows that you''re not exactly clear about your abstraction, or the boundaries of the object. Most of the time, you don''t need a ''Set'' for your internal variables, and quite a lot of the time, you don''t even need a ''Get'' either.

quote:For something like a vector, where you are likely to want to reference the variables a lot, use of Get() and Set() are a pain in the arse.

If you mean a vector in the coordinate/positioning sense, then yes, there''s little reason not to use a struct/public members, since you tend to have to be acutely aware of the datatype you''re dealing with anyway. But I think most of the posts here are addressing slightly higher-level data types.

This topic is closed to new replies.

Advertisement