Private fields

Started by
6 comments, last by ArnoAtWork 22 years, 2 months ago
I program principally in C++ since for years because of the OO approach. Now the program become more and more complex and its often that, to avoid the access problems of private fields, I put all in public. I know that I break the C++ rules, but what the interest to take care at your values in projects where you control everything. Moreover what the interest to implement accessors everywhere if you can directly access at your data? I think that I am a little bit confused. But Its explained in books that private allow you not to have modified data. But if you implement a SetData() and a GetData(), where is the interest?
Advertisement
The important thing is to know when encapsulation is needed, and when it isn''t

If you are finding that you need lots of Get() and Set() functions, DONT just make everything public. This is a sign that there is something fundamentally flawed with your design, and you should take this opportunity to rethink it.

Sometimes it IS a case of making stuff public - e.g in a vector or matrix class. More often, you should be thinking more carefully about what each class is doing and how the interaction between them works. A well designed OO system should not need lots of accessors.
To make all data public defeats the purpose of object oriented design. Just using classes to store data doesn''t mean that one is using OOP. Like the previous person said, if you have so many getters and setters maybe something is wrong with your design. Don''t think of classes as a container that just holds data. Think of a class as a thing that operates upon its data and holds states.

DO NOT program to the data in an class. Program to an _interface_ that the class presents. Getters and setters should ONLY present access to private data that is ESSENTIAL for other classes to access.

RandomTask
Also the purpose of Get/Set methods is that you can perform error checking on the data to make sure it is set correctly. For example, if you have a class with an integer in it that you don''t want to hold a negative number, but you make it public, then the user of the class could still make the number negative, even if you say they shouldn''t. This could cause your whole class to blowup. If you have the integer private, and use a Set method to set that integer, you can check the value and if it is negative, discard it and return an error.

One reason not to use get/set access is if speed is required, like in a game. Call these funcitons can slow the game down, whereas setting them public and accessing them directly can be much quicker. You could inline the get/set methods for speed, but that does not always work.

I don''t entirely agree with Sandman''s last statement that a good OOP design doesn''t have a lot of accessors. But he does have a point. If you do find you have a lot of them, take a good look at your design to see if you can streamline it. Maybe you can or maybe you can''t. Don''t just tear it apart because you have a lot of accessors.

---
Make it work.
Make it fast.

"Commmmpuuuuterrrr.." --Scotty Star Trek IV:The Voyage Home
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
I am currently a physics engine where I use particle system. Each particle has a speed, position, acceleration, mass and size. So I had to develop:

SetIniSpeed(....)
SetIniAccel(....)
SetMass(...)
etc...

Put all fields in public could avoid all these function even if I use "inline". In this way, maybe a structure is more logical than a class. But as a "UpdatePosition(time)" function should be develop for particle, particle system, rigid body etc..., it seems to be more logical to use a method(in class) rather than a function.

I learned C++ during two years at school and after two others ones, I had to program in C. Maybe this way is not really normal. Anyway, if the structure is in C language, why it is not called a OO language?
C++ is not an object-oriented language because—if for no other reason—it doesn''t force you to use the object-oriented paradigm.

I completely agree with what''s been said above. I feel compelled to add that in addition to error checking, the reason not to make data public is to guarantee that all client code has to go through points that you define; you have to make appropriate functions that can guarantee that there are no side-effects so your objects behave just as you design them to. Of course, there are times that''s not a big problem, such as a vector class. That''s the sort of case where it''s best to use a struct (which, as many people end up point out around here, differs from a class only in that the default access is public and not private) with maybe a constructor and a number of member functions. But always try to expose as little as necessary.
quote:Original post by ArnoAtWork
I am currently a physics engine where I use particle system. Each particle has a speed, position, acceleration, mass and size. So I had to develop:

SetIniSpeed(....)
SetIniAccel(....)
SetMass(...)
etc...



While I dont know exactly what you are doing, let me take some guesses and make up some stuff. It may be wildy wrong for what you are doing, but hopefully it will give you some ideas.

Perhaps you dont want to make all these fields publicly accessible. Perhaps, you should have a constructor that takes the initial speed, velocity, etc. Then you could have an update method which takes a time parameter (how much time has elapsed). The update function could then do things like
    //updates the particle, returns true if the partical is still//active, false if we are done with it (ie: it burned out or something).bool CParticle::update(float time){   lifetime -= time;   if (lifetime < 0)   {      //lets assume particleList is a static member of       //CParticle, and that it is of some type of array or       //linked list class type      CParticle::particleList.remove(this);      return false;   };   //simplified physics...this is faster than integrating   //but not as accurate.   position += velocity * time;   velocity += accelleration * time;   //do somethin here to modify accelleration to take    //gravity or wind resistance or whatver into account   size += growthRate*time;   return true;};    


See how here, the partical takes care of itself? You dont have to toy around with it's velocities and stuff, thus you dont need any set and get accessors.

Edited by - LordKronos on January 30, 2002 1:00:59 PM
Ron FrazierKronos Softwarewww.kronos-software.comMiko & Molly - Taking Puzzle Games to A Whole New Dimension
Accessor methods (Get/Set) allow you to specify pre- and post-conditions. It also allows you to do neat tricks like returning a reference to a proxy representation of the data (this is a great technique to use when writing smart pointers.)

If you let your data members be publicly accessed it becomes much harder to change the internal implementation of a class, perform thread synchronization, etc.

If the Get/Set prefix on a method name is bothering you (it looks ugly IMHO) you can always do this:

class Test{    public:        Test() : value_(0)        {}        int  internalInt() const  // get method        { return value_; }        void internalInt(int i)   // set method        { value_ = i; }        private:        int value_;};Test t;int i = t.internalInt(); // geti += 20;t.internalInt(i);  // set 


Also don''t forget that data members don''t have to be set one at a time. You can write methods like

SetXYZ(float x, float y, float z); // sets XYZ - requires 3 parameters.

SetXYZ(float* data, DataFlagsEnum flags); // sets XYZ based off an array of floats. The ''flags'' bit fields tell the method what the array holds and what data members to set. Example: SetXYZ(&data, FLAG_X | FLAG_Z); // array contains X and Z components.

Another alternative (mainly something I use for distributed programming) is creating a templated property class that can be used for representing a class data member. These property classes allow you to provide read/write/read-write access to a data member, synchronized access, distributed/proxy access, etc.

If performance is a big issue for you (the data member is accessed frequently in a tight loop) you might want to consider using ''inline'' or public data members (in the worst case.)

Regards,


Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com

This topic is closed to new replies.

Advertisement