I have about 15~20 member variables which needs to be accessed, I was wondering
if it would be good just to let them be public instead of giving every one of them
get/set functions.
The code would be something like
class A { // a singleton class
public:
static A* get();
B x, y, z;
// ... a lot of other object that should only have one copy
// and doesn't change often
private:
A();
virtual ~A();
static A* a;
};
I have also thought about putting the variables into an array, but I don't
know the best way to do a lookup table, would it be better to put them in an array?
EDIT:
Is there a better way than Singleton class to put them in a collection
The C++ world isn't quite as hung up on "everything must be hidden behind accessors/mutators/whatever-they-decide-to-call-them-todays" as some OO-supporting languages.
With that said, it's a bit hard to say what the best approach is, given your limited description.
If your class is simply a 'bag of data' for some other process, than using a struct instead of a class (the only difference is that all members default to public) can be appropriate.
If the class actually does something, however, you might find it more appropriate to group your get/set routines together by function/aspect or interface.
As I mentioned, it's a bit hard to tell without more information.
EDIT: Singleton classes are not smelly code in and of themselves, but you do need to be a bit careful with them. If a singleton is taking care of preference data or something similar, it only makes sense to make individual accessors for each data element.
If, on the other hand, you're storing generic input data in a singleton, it might be time to rethink the design.
You could place them in a POD structure and provide access to an object of that type :
struct VariablesHolder
{
int a;
float b;
char c[20];
};
class A
{
public:
A() : vh()
{
}
VariablesHolder& Access()
{
return vh;
}
const VariablesHolder& Get() const
{
return vh;
}
private:
VariablesHolder vh;
};
No that wouldn't be good. Image you want to change the way they are accessed in the future. For example remove one member variable and let the get/set functions compute its value.
It really depends on why you want to give access to them, how likely they are to change, how much code uses them, how problematic having to rewrite or recompile that code is, how fast access needs to be, whether you need/want virtual access, what's more convenient and intuitive in the using code etc.. Wanting to give access to so many things may be a sign of poor design, or it may be 100% appropriate. Using get/set functions has much more potential benefit for volatile (unstable / possibly subject to frequent tweaks) low-level code that could be used by a large number of client apps.
Given your edit, an array makes sense if your client is likely to want to access the values in a loop, or a numeric index is inherently meaningful. For example, if they're chronologically ordered data samples, an index sounds good. Summarily, arrays make it easier to provide algorithms to work with any or all of the indices - you have to consider whether that's useful to your clients; if not, try to avoid it as it may make it easier to mistakenly access the wrong values, particularly if say two people branch some code, add an extra value at the end, then try to merge their changes. Sometimes it makes sense to provide arrays and named access, or an enum with meaningful names for indices.
This is a horrible design choice, as it allows any component to modify any of these variables. Furthermore, since access to these variables is done directly, you have no way to impose any invariant on the values, and if suddenly you decide to multithread your program, you won't have a single set of functions that need to be mutex-protected, but rather you will have to go off and find every single use of every single data member and individually lock those usages. In general, one should:
Not use singletons or global variables; they introduce subtle, implicit dependencies between components that allow seemingly independent components to interfere with each other.
Make variables const wherever possible and provide setters only where absolutely required.
Never make variables public (unless you are creating a POD struct, and even then, it is best to create POD structs only as an internal implementation detail and not expose them in the API).
Also, you mentioned that you need to use an array. You can use vector<B> or vector<B*> to create a dynamically-sized array of objects of type B or type B*. Rather than using A::getA() to access your singleton instance; it would be better to have functions that need type A to take a parameter of type const A&. This will make the dependency explicit, and it will also limit which functions can modify the members of that class (pass A* or A& to functions that need to mutate it).
As a convention, if you want a data structure to hold several public fields (plain old data), I would suggest using a struct (and use in tandem with other classes -- builder, flyweight, memento, and other design patterns).
Classes generally mean that you're defining an encapsulated data type, so the OOP rule is to hide data members.
In terms of efficiency, modern compilers optimize away calls to accessors/mutators, so the impact on performance would be non-existent.
In terms of extensibility, methods are definitely a win because derived classes would be able to override these (if virtual). Another benefit is that logic to check/observe/notify data can be added if data is accessed via member functions.
Public members in a base class is generally a difficult to keep track of.
Related
I'm a computational physicist trying to learn how to code properly. I've written several program by now, but the following canonical example keeps coming back, and I'm unsure as to how to handle it. Let's say that I have a composition of two objects such as
class node
{
int position;
};
class lattice
{
vector <node*> nodes;
double distance (node*,node*);
};
Now, this will not work, because position is a private member of node. I know of two ways to solve this: either you create an accessor such as getpos(){return position}, or make lattice a friend of node.
The second of these solutions seems a lot easier to me. However, I am under the impression that it is considered slightly bad practice, and that one generally ought to stick to accessors and avoid friend. My question is this: When should I use accessors, and when should I use friendship for compositions such as these?
Also, a bonus question that has been bugging me for some time: Why are compositions preferred to subclasses in the first place? To my understanding the HAS-A mnemonic argues this, but, it seems more intuitive to me to imagine a lattice as an object that has an object called node. That would then be an object inside of an object, e.i. a subclass?
Friend is better suited if you give access rights to only specific classes, rather than to all. If you define getpos(){return position}, position information will be publicly accessible via that getter method. If you use friend keyword, on the other hand, only the lattice class will be able to access position info. Therefore, it is purely dependent on your design decisions, whether you wanna make the information publicly accessible or not.
You made a "quasi class", this a textbook example of how not to do OOP because changing position doesn't change anything else in node. Even if changing position would change something in node, I would rethink the structure to avoid complexity and improve the compiler's ability to optimize your code.
I’ve witnessed C++ and Java programmers routinely churning out such
classes according to a sort of mental template. When I ask them to
explain their design, they often insist that this is some sort of
“canonical form” that all elementary and composite item (i.e.
non-container) classes are supposed to take, but they’re at a loss to
explain what it accomplishes. They sometimes claim that we need the
get and set functions because the member data are private, and, of
course, the member data have to be private so that they can be changed
without affecting other programs!
Should read:
struct node
{
int position;
};
Not all classes have to have private data members at all. If your intention is to create a new data type, then it may be perfectly reasonable for position to just be a public member. For instance, if you were creating a type of "3D Vectors", that is essentially nothing but a 3-tuple of numeric data types. It doesn't benefit from hiding its data members since its constructor and accessor methods have no fewer degrees of freedom than its internal state does, and there is no internal state that can be considered invalid.
template<class T>
struct Vector3 {
T x;
T y;
T z;
};
Writing that would be perfectly acceptable - plus overloads for various operators and other functions for normalizing, taking the magnitude, and so on.
If a node has no illegal position value, but no two nodes in a lattice cannot have the same position or some other constraint, then it might make sense for node to have public member position, while lattice has private member nodes.
Generally, when you are constructing "algebraic data types" like the Vector3<T> example, you use struct (or class with public) when you are creating product types, i.e. logical ANDs between other existent types, and you use std::variant when you are creating sum types, i.e. logical ORs between existent types. (And for completeness' sake, function types then take the place of logical implications.)
Compositions are preferred over inheritance when, like you say, the relationship is a "has-a" relationship. Inheritance is best used when you are trying to extend or link with some legacy code, I believe. It was previously also used as a poor approximation of sum types, before std::variant existed, because the union keyword really doesn't work very well. However, you are almost always better off using composition.
Concerning your example code, I am not sure that this poses a composition. In a composition, the child object does not exist as an independent entity. As a rule of thumb, it's life time is coupled with the container. Since you are using a vector<node*> nodes, I assume that the nodes are created somewhere else and lattice only has a pointer to these objects. An example for a composition would be
class lattice {
node n1; // a single object
std::vector<node> manyNodes;
};
Now, addressing the questions:
"When should I use accessors, and when should I use friendship for compositions such as these?"
If you use plenty of accessors in your code, your are creating structs and not classes in an OO sense. In general, I would argue that besides certain prominent exceptions such as container classes one rarely needs setters at all. The same can be argued for simple getters for plain members, except when the returning the property is a real part of the class interface, e.g. the number of elements in a container. Your interface should provide meaningful services that manipulate the internal data of your object. If you frequently get some internal data with a getter, then compute something and set it with an accessor you should put this computation in a method.
One of the main reasons why to avoid ´friend´ is because it introduces a very strong coupling between two components. The guideline here is "low coupling, high cohesion". Strong coupling is considered a problem because it makes code hard to change, and most time on software projects is spent in maintenance or evoluation. Friend is especially problematic because it allows unrelated code to be based on internal properties of your class, which can break encapsulation. There are valid use-cases for ´friend´ when the classes form a strongly related cluster (aka high cohesion).
"Why are compositions preferred to subclasses in the first place?"
In general, you should prefer plain composition over inheritance and friend classes since it reduces coupling. In a composition, the container class can only access the public interface of the contained class and has no knowledge about the internal data.
From a pure OOP point of view, your design has some weaknesses and is probably not very OO. One of the basic principles of OOP is encapsulation which means to couple related data and behavior into objects. The node class e.g. does not have any meaning other than storing a position, so it does not have any behavior. It seems that you modeled the data of your code but not the behavior. This can be a very appropriate design and lead to good code, but it not really object-oriented.
"To my understanding the HAS-A mnemonic argues this, but, it seems more intuitive to me to imagine a lattice as an object that has an object called node. That would then be an object inside of an object, e.i. a subclass?"
I think you got this wrong. Public inheritance models an is-a-relationship.
class A: public B {};
It basically says that objects of class A are a special kind of B, fulfilling all the assumptions that you can make about objects of type B. This is known as the Liskov substitution principle. It basically says that everywhere in your code where you use a B you should be able to also use an A. Considering this, class lattice: public node would mean that every lattice is a node. On the other hand,
class lattice {
int x;
node n;
int y;
};
means that an object of type lattice contains another object of type node, in C++ physically placed together with x and y. This is a has-a-relationship.
I was trying to write down some implementations for a couple of data structures that I'm interested in for a multithreaded / concurrent scenario.
A lot of functional languages, pretty much all that I know of, design their own data structures in such a way that they are immutable, so this means that if you are going to add value to an instance t1 of T, you really get a new instance of T that packs t1 + value.
container t;
container s = t; //t and s refer to the same container.
t.add(value); //this makes a copy of t, and t is the copy
I can't find the appropriate keywords to do this in C++11; there are keywords, semantics and functions from the standard library that are clearly oriented to the functional approach, in particular I found that:
mutable it's not for runtime, it's more likely to be an hint for the compiler, but this keyword doesn't really help you in designing a new data structure or use a data structure in an immutable way
swap doesn't works on temporaries, and this is a big downside in my case
I also don't know how much the other keywords / functions can help with such design, swap was one of them really close to something good, so I could at least start to write something, but apparently it's limited to lvalues .
So I'm asking: it's possible to design immutable data structure in C++11 with a functional approach ?
You simply declare a class with private member variables and you don't provide any methods to change the value of these private members. That's it. You initialize the members only from the constructors of the class. Noone will be able to change the data of the class this way. The tool of C++ to create immutable objects is the private visibility of the members.
mutable: This is one of the biggest hacks in C++. I've seen at most 2 places in my whole life where its usage was reasonable and this keyword is pretty much the opposite of what you are searching for. If you would search for a keyword in C++ that helps you at compile time to mark data members then you are searching for the const keyword. If you mark a class member as const then you can initialize it only from the INITIALIZER LIST of constructors and you can no longer modify them throughout the lifetime of the instance. And this is not C++11, it is pure C++. There are no magic language features to provide immutability, you can do that only by programming smartly.
In c++ "immutability" is granted by the const keyword. Sure - you still can change a const variable, but you have to do it on purpose (like here). In normal cases, the compiler won't let you do that. Since your biggest concern seems to be doing it in a functional style, and you want a structure, you can define it yourself like this:
class Immutable{
Immutable& operator=(const Immutable& b){} // This is private, so it can't be called from outside
const int myHiddenValue;
public:
operator const int(){return myHiddenValue;}
Immutable(int valueGivenUponCreation): myHiddenValue(valueGivenUponCreation){}
};
If you define a class like that, even if you try to change myHiddenValue with const_cast, it won't actually do anything, since the value will be copied during the call to operator const int.
Note: there's no real reason to do this, but hey - it's your wish.
Also note: since pointers exist in C++, you still can change the value with some kind of pointer magic (get the address of the object, calc the offset, etc), but you can't really help that. You wouldn't be able to prevent that even when using an functional language, if it had pointers.
And on a side note - why are you trying to force yourself in using C++ in a functional manner? I can understand it's simpler for you, and you're used to it, but functional programming isn't often used because of its downfalls. Note that whenever you create a new object, you have to allocate space. It's slower for the end-user.
Bartoz Milewski has implemented Okasaki's functional data structures in C++. He gives a very thorough treatise on why functional data structures are important for concurrency. In that treatise, he explains the need in concurrency to construct an object and then afterwards make it immutable:
Here’s what needs to happen: A thread has to somehow construct the
data that it destined to be immutable. Depending on the structure of
that data, this could be a very simple or a very complex process. Then
the state of that data has to be frozen — no more changes are
allowed.
As others have said, when you want to expose data in C++ and have it not be available for changing, you make your function signature look like this:
class MutableButExposesImmutably
{
private:
std::string member;
public:
void complicatedProcess() { member = "something else"; } // mutates
const std::string & immutableAccessToMember() const {
return member;
}
};
This is an example of a data structure that is mutable, but you can't mutate it directly.
I think what you are looking for is something like java's final keyword: This keyword allows you to construct an object, but thereafter the object remains immutable.
You can do this in C++. The following code sample compiles. Note that in the class Immutable, the object member is literally immutable, (unlike what it was in the previous example): You can construct it, but once constructed, it is immutable.
#include <iostream>
#include <string>
using namespace std;
class Immutable
{
private:
const std::string member;
public:
Immutable(std::string a) : member(a) {}
const std::string & immutable_member_view() const { return member; }
};
int main() {
Immutable foo("bar");
// your code goes here
return 0;
}
Re. your code example with s and t. You can do this in C++, but "immutability" has nothing to do with that question, if I understand your requirements correctly!
I have used containers in vendor libraries that do operate the way you describe; i.e. when they are copied they share their internal data, and they don't make a copy of the internal data until it's time to change one of them.
Note that in your code example, there is a requirement that if s changes then t must not change. So s has to contain some sort of flag or reference count to indicate that t is currently sharing its data, so when s has its data changed, it needs to split off a copy instead of just updating its data.
So, as a very broad outline of what your container will look like: it will consist of a handle (e.g. a pointer) to some data, plus a reference count; and your functions that update the data all need to check the refcount to decide whether to reallocate the data or not; and your copy-constructor and copy-assignment operator need to increment the refcount.
I am doing a large project for the first time. I have lots of classes and some of them have public variables, some have private variables with setter and getter methods and same have both types.
I decided to rewrite this code to use primarily only one type. But I don't know which I should use (variables which are used only for methods in the same object are always private and are not subject of this question).
I know the theory what public and private means, but what is used in the real world and why?
private data members are generally considered good because they provide encapsulation.
Providing getters and setters for them breaks that encapsulation, but it's still better than public data members because there's only once access point to that data.
You'll notice this during debugging. If it's private, you know you can only modify the variable inside the class. If it's public, you'll have to search the whole code-base for where it might be modified.
As much as possible, ban getters/setters and make properties private. This follows the principle of information hiding - you shouldn't care about what properties a class has. It should be self-contained. Of course, in practice this isn't feasible, and if it is, a design that follows this will be more cluttered and harder to maintain than one that doesn't.
This is of course a rule of thumb - for example, I'd just use a struct (equivalent with a class with public access) for, say, a simple point class:
struct Point2D
{
double x;
double y;
};
Since you say that you know the theory, and other answers have dug into the meaning of public/private, getters and setters, I'd like to focus myself on the why of using accessors instead of creating public attributes (member data in C++).
Imagine that you have a class Truck in a logistic project:
class Truck {
public:
double capacity;
// lots of more things...
};
Provided you are northamerican, you'll probably use gallons in order to represent the capacity of your trucks. Imagine that your project is finished, it works perfectly, though many direct uses of Truck::capacity are done. Actually, your project becomes a success, so some european firm asks you to adapt your project to them; unfortunately, the project should use the metric system now, so litres instead of gallons should be employed for capacity.
Now, this could be a mess. Of course, one possibility would be to prepare a codebase only for North America, and a codebase only for Europe. But this means that bug fixes should be applied in two different code sources, and that is decided to be unfeasible.
The solution is to create a configuration possibility in your project. The user should be able to set gallons or litres, instead of that being a fixed, hardwired choice of gallons.
With the approach seen above, this will mean a lot of work, you will have to track down all uses of Truck::capacity, and decide what to do with them. This will probably mean to modify files along the whole codebase. Let's suppose, as an alternative, that you decided a more theoretic approach.
class Truck {
public:
double getCapacity() const
{ return capacity; }
// lots of more things...
private:
double capacity;
};
A possible, alternative change involves no modification to the interface of the class:
class Truck {
public:
double getCapacity() const
{ if ( Configuration::Measure == Gallons ) {
return capacity;
} else {
return ( capacity * 3.78 );
}
}
// lots of more things...
private:
double capacity;
};
(Please take int account that there are lots of ways for doing this, that one is only one possibility, and this is only an example)
You'll have to create the global utility class configuration (but you had to do it anyway), and add an include in truck.h for configuration.h, but these are all local changes, the remaining of your codebase stays unchanged, thus avoiding potential bugs.
Finally, you also state that you are working now in a big project, which I think it is the kind of field in which these reasons actually make more sense. Remember that the objective to keep in mind while working in large projects is to create maintainable code, i.e., code that you can correct and extend with new functionalities. You can forget about getters and setters in personal, small projects, though I'd try to make myself used to them.
Hope this helps.
There is no hard rule as to what should be private/public or protected.
It depends on the role of your class and what it offers.
All the methods and members that constitute the internal workings of
the class should be made private.
Everything that a class offers to the outside world should be public.
Members and methods that may have to be extended in a specialization of this class,
could be declared as protected.
From an OOP point of view getters/setters help with encapsulation and should therefore always be used. When you call a getter/setter the class can do whatever it wants behind the scenes and the internals of the class are not exposed to the outside.
On the other hand, from a C++ point of view, it can also be a disadvantage if the class does lots of unexpected things when you just want to get/set a value. People like to know if some access results in huge overhead or is simple and efficient. When you access a public variable you know exactly what you get, when you use a getter/setter you have no idea.
Especially if you only do a small project, spending your time writing getters/setters and adjusting them all accordingly when you decide to change your variable name/type/... produces lots of busywork for little gain. You'd better spend that time writing code that does something useful.
C++ code commonly doesn't use getters/setters when they don't provide real gain. If you design a 1,000,000-line project with lots of modules that have to be as independent as possible it might make sense, but for most normal-sized code you write day to day they are overkill.
There are some data types whose sole purpose is to hold well-specified data. These can typically be written as structs with public data members. Aside from that, a class should define an abstraction. Public variables or trivial setters and getters suggest that the design hasn't been thought through sufficiently, resulting in an agglomeration of weak abstractions that don't abstract much of anything. Instead of thinking about data, think about behavior: this class should do X, Y, and Z. From there, decide what internal data is needed to support the desired behavior. That's not easy at first, but keep reminding yourself that it's behavior that matters, not data.
Private member variables are preferred over public member variables, mainly for the reasons stated above (encapsulation, well-specified data, etc..). They also provide some data protection as well, since it guarantees that no outside entity can alter the member variable without going through the proper channel of a setter if need be.
Another benefit of getters and setters is that if you are using an IDE (like Eclipse or Netbeans), you can use the IDE's functionality to search for every place in the codebase where the function is called. They provide visibility as to where a piece of data in that particular class is being used or modified. Also, you can easily make the access to the member variables thread safe by having an internal mutex. The getter/setter functions would grab this mutex before accessing or modifying the variable.
I'm a proponent of abstraction to the point where it is still useful. Abstraction for the sake of abstraction usually results in a cluttered mess that is more complicated than its worth.
I've worked with complex rpgies and many games and i started to follow this rule of thumb.
Everything is public until a modification from outside can break something inside, then it should be encapsulated.(corner count in a triangle class for example)
I know info hiding principles etc but really don't follow that.
Public variables are usually discouraged, and the better form is to make all variables private and access them with getters and setters:
private int var;
public int getVar() {
return var;
}
public void setVar(int _var) {
var = _var;
}
Modern IDEs like Eclipse and others help you doing this by providing features like "Implement Getters and Setters" and "Encapsulate Field" (which replaces all direct acccesses of variables with the corresponding getter and setter calls).
Any opinions on best way to organize members of a class (esp. when there are many) in C++. In particular, a class has lots of user parameters, e.g. a class that optimizes some function and has number of parameters such as # of iterations, size of optimization step, specific method to use, optimization function weights etc etc. I've tried several general approaches and seem to always find something non-ideal with it. Just curious others experiences.
struct within the class
struct outside the class
public member variables
private member variables with Set() & Get() functions
To be more concrete, the code I'm working on tracks objects in a sequence of images. So one important aspect is that it needs to preserve state between frames (why I didn't just make a bunch of functions). Significant member functions include initTrack(), trackFromLastFrame(), isTrackValid(). And there are a bunch of user parameters (e.g. how many points to track per object tracked, how much a point can move between frames, tracking method used etc etc)
If your class is BIG, then your class is BAD.
A class should respect the Single Responsibility Principle , i.e. : A class should do only one thing, but should do it well. (Well "only one" thing is extreme, but it should have only one role, and it has to be implemented clearly).
Then you create classes that you enrich by composition with those single-role little classes, each one having a clear and simple role.
BIG functions and BIG classes are nest for bugs, and misunderstanding, and unwanted side effects, (especially during maintainance), because NO MAN can learn in minutes 700 lines of code.
So the policy for BIG classes is: Refactor, Composition with little classes targetting only at what they have do.
if i had to choose one of the four solutions you listed: private class within a class.
in reality: you probably have duplicate code which should be reused, and your class should be reorganized into smaller, more logical and reusable pieces. as GMan said: refactor your code
First, I'd partition the members into two sets: (1) those that are internal-only use, (2) those that the user will tweak to control the behavior of the class. The first set should just be private member variables.
If the second set is large (or growing and changing because you're still doing active development), then you might put them into a class or struct of their own. Your main class would then have a two methods, GetTrackingParameters and SetTrackingParameters. The constructor would establish the defaults. The user could then call GetTrackingParameters, make changes, and then call SetTrackingParameters. Now, as you add or remove parameters, your interface remains constant.
If the parameters are simple and orthogonal, then they could be wrapped in a struct with well-named public members. If there are constraints that must be enforced, especially combinations, then I'd implement the parameters as a class with getters and setters for each parameter.
ObjectTracker tracker; // invokes constructor which gets default params
TrackerParams params = tracker.GetTrackingParameters();
params.number_of_objects_to_track = 3;
params.other_tracking_option = kHighestPrecision;
tracker.SetTrackingParameters(params);
// Now start tracking.
If you later invent a new parameter, you just need to declare a new member in the TrackerParams and initialize it in ObjectTracker's constructor.
It all depends:
An internal struct would only be useful if you need to organize VERY many items. And if this is the case, you ought to reconsider your design.
An external struct would be useful if it will be shared with other instances of the same or different classes. (A model, or data object class/struct might be a good example)
Is only ever advisable for trivial, throw-away code.
This is the standard way of doing things but it all depends on how you'll be using the class.
Sounds like this could be a job for a template, the way you described the usage.
template class FunctionOptimizer <typename FUNCTION, typename METHOD,
typename PARAMS>
for example, where PARAMS encapsulates simple optimization run parameters (# of iterations etc) and METHOD contains the actual optimization code. FUNCTION describes the base function you are targeting for optimization.
The main point is not that this is the 'best' way to do it, but that if your class is very large there are likely smaller abstractions within it that lend themselves naturally to refactoring into a less monolithic structure.
However you handle this, you don't have to refactor all at once - do it piecewise, starting small, and make sure the code works at every step. You'll be surprised how much better you quickly feel about the code.
I don't see any benefit whatsoever to making a separate structure to hold the parameters. The class is already a struct - if it were appropriate to pass parameters by a struct, it would also be appropriate to make the class members public.
There's a tradeoff between public members and Set/Get functions. Public members are a lot less boilerplate, but they expose the internal workings of the class. If this is going to be called from code that you won't be able to refactor if you refactor the class, you'll almost certainly want to use Get and Set.
Assuming that the configuration options apply only to this class, use private variables that are manipulated by public functions with meaningful function names. SetMaxInteriorAngle() is much better than SetMIA() or SetParameter6(). Having getters and setters allows you to enforce consistency rules on the configuration, and can be used to compensate for certain amounts of change in the configuration interface.
If these are general settings, used by more than one class, then an external class would be best, with private members and appropriate functions.
Public data members are usually a bad idea, since they expose the class's implementation and make it impossible to have any guaranteed relation between them. Walling them off in a separate internal struct doesn't seem useful, although I would group them in the list of data members and set them off with comments.
I personally find it weird/ugly when a class uses a getter to access its own member data. I know the performance impact is none but I just don't like to see all those method calls.
Are there any strong arguments either way, or is it just one of those things that's personal preference and should be left to each coder, or arbitrarily controlled in a coding standard?
Update: I'm meaning simple getters, specifically for a class' non-public members.
The reason you might want to use a getter/setter is because it conceals the implementation. You won't have to rewrite all of your code if you are using getters/setters in case the implementation does change, because those members can continue to work.
EDIT based on the many clever comments:
As for a class using setters and getters on itself, that may depend on the particulars. After all, the implementation of a particular class is available to the class itself. In the cases where a class is normally instantiated, the class should use the member values directly for its own members (private or otherwise) and its parent classes (if they are protected) and only use getters/setters in the case that those members are private to the parent class.
In the case of an abstract type, which will usually not contain any implementation at all, it should provide pure virtual getters and setters and use only those in the methods it does implement.
Willingness to use getters/setters within class member implementation is the canary in the mine telling that your class is growing unreasonably. It tells that your class is trying to do too many different things, that it serves several purposes where it should serve one instead.
In fact, this is usually encountered when you are using one part of your class to store or access your data, and another part to make operations on it. Maybe you should consider using a standalone class to store and give access to your data, and another one to provide a higher view, with more complex operations with your data.
THE OBVIOUS
getters and setters for protected members makes as much sense as for public... derived classes are just another form of client code, and encapsulating implementation details from them can still be useful. I'm not saying always do it, just to weight pros and cons along the normal lines.
getters and setters for private members is rarely a net benefit, though:
it does provide the same kind of encapsulation benefits
single place for breakpoints/logging of get/set + invariant checks during dev (if used consistently)
virtual potential
etc...
but only to the presumably relatively small implementation of the same struct/class. In enterprise environments, and for public/protected member data, those benefits can be substantial enough to justify get/set methods: a logging function may end up having millions of lines of code depedent on it, and hundreds or thousands of libraries and apps for which a change to a header may trigger recompilation. Generally a single class implementation shouldn't be more than a few hundred (or at worst thousand) lines - not big or complex enough to justify encapsulating internal private data like this... it could be said to constitute a "code smell".
THE NOT-SO OBVIOUS
get/set methods can very occasionally be more readable than direct variable access (though more often less readable)
get/set methods may be able to provide a more uniform and convenient interface for code-generated member or friend methods (whether from macros or external tools/scripts)
less work required to transition between being a member or friend to a freestanding helper function should that become possible
implementation may be rendered more understandable (and hence maintainable) to people who're normally only users of the class (as more operations are expressed via, or in the style of, the public interface)
It's a bit out of scope for the question, but it's worth noting that classes should generally provide action-oriented commands, event-triggered callbacks etc. rather than encouraging a get/set usage pattern.
It seems most people didn't read your question properly, the question is concerning whether or not class methods accessing its own class' members should use getters and setters; not about an external entity accessing the class' members.
I wouldn't bother using getter and setter for accessing a class' own members.
However, I also keep my classes small (typically about 200-500 lines), such that if I do need to change the fields or change its implementations or how they are calculated, search and replace wouldn't be too much work (indeed, I often change variable/class/function names in the early development period, I'm picky name chooser).
I only use getter and setters for accessing my own class members when I am expecting to change the implementation in the near future (e.g. if I'm writing a suboptimal code that can be written quickly, but plans to optimize it in the future) that might involve radically changing the data structure used. Conversely, I don't use getter and setter before I already have the plan; in particular, I don't use getter and setter in expectation of changing things I'm very likely never going to change anyway.
For external interface though, I strictly adhere to the public interface; all variables are private, and I avoid friend except for operator overloads; I use protected members conservatively and they are considered a public interface. However, even for public interface, I usually still avoid having direct getters and setters methods, as they are often indicative of bad OO design (every OO programmers in any language should read: Why getter and setter methods are Evil). Instead, I have methods that does something useful, instead of just fetching the values. For example:
class Rectangle {
private:
int x, y, width, height;
public:
// avoid getX, setX, getY, setY, getWidth, setWidth, getHeight, setHeight
void move(int new_x, int new_y);
void resize(int new_width, int new_height);
int area();
}
The only advantage is that it allows changing internal representation without changing external interface, permitting lazy evaluation, or why not access counting.
In my experience, the number of times I did this is very, very low. And it seems you do, I also prefer to avoid the uglyness and weightyness of getter/setters. It is not that difficult to change it afterwards if I really need it.
As you speak about a class using its own getter/setters in its own implementation functions, then you should consider writing non-friend non-member functions where possible. They improve encapsulation as explained here.
An argument in favor of using getters is that you might decide one day to change how the member field is calculated. You may decide that you need it to be qualified with some other member, for instance. If you used a getter, all you have to do is change that one getter function. If you didn't you have to change each and every place where that field is used currently and in the future.
Just a crude example. Does this help?
struct myclass{
int buf[10];
int getAt(int i){
if(i >= 0 && i < sizeof(buf)){
return buf[i];
}
}
void g(){
int index = 0;
// some logic
// Is it worth repeating the check here (what getAt does) to ensure
// index is within limits
int val = buf[index];
}
};
int main(){}
EDIT:
I would say that it depends. In case the getters do some kind of validation, it is better to go through the validation even if it means the class members being subjected to that validation. Another case where going through a common entry point could be helpful is when the access needs to be essentially in a sequential and synchronized manner e.g. in a multithreaded scenario.
Protecting a member variable by wrapping its access with get/set functions has its advantages. One day you may wish to make your class thread-safe - and in that instance, you'll thank yourself for using those get/set functions
this is actually for supporting the object oriented-ness of the class by abstracting the way to get(getter). and just providing its easier access.
Simple answer. If you are writing a one shoot program, that will never change, you can leave the getters at peace and do without any.
However if you write a program that could change or been written over time, or others might use that code, use getters.
If you use getters it helps change the code faster later on, like putting a guard on the property to verify correctness of value, or counting access to the property(debugging).
Getters to me are about easy possibilities(free lunch). The programmer who write the code does not need getters, he wants them.
hope that help.
My thoughts are as follows.
Everything should be static, constant, and private if possible.
As you need a variable to be instanced meaning more than one unique
copy you remove static.
As you need a variable to be modifiable you remove the const.
As you need a class/variable to be accessed by other classes you remove
the private.
The Usage of Setters/Getters - General Purpose.
Getter's are okay if the value is to ONLY be changed by the class and
we want to protect it. This way we can retrieve the current state of
this value without the chance of it's value getting changed.
Getter's should not be used if you are planning to provide a Setter
with it. At this point you should simply convert the value to public
and just modify it directly. Since this is the intent with a Get/Set.
A Setter is plain useless if you are planning to do more then simply
"this.value = value". Then you shouldn't be calling it "SetValue"
rather describe what it is actually doing.
If let's say you want to make modifications to a value before you
"GET" it's value. Then DO NOT call it "GetValue". This is ambiguous
to your intent and although YOU might know what's happening. Someone
else wouldn't unless they viewed the source code of that function.
If let's say you are indeed only Getting/Setting a value, but you are
doing some form of security. I.e. Size check, Null Check, etc.. this
is an alternative scenario. However you should still clarify that in
the name E.g. "SafeSetValue" , "SafeGetValue" or like in the "printf"
there is "printf_s".
Alternatives to the Get/Set situations
An example that I personally have. Which you can see how I handle a
Get/Set scenario. Is I have a GameTime class which stores all kinds
of values and every game tick these values get changed.
https://github.com/JeremyDX/DX_B/blob/master/DX_B/GameTime.cpp
As you will see in the above my "GETS" are not actually "GETS" of
values except in small cases where modification wasn't needed. Rather
they are descriptions of values I am trying to retrieve out of this
GameTime class. Every value is "Static Private". I cannot do Const
given the information is obtained until runtime and I keep this
static as there is no purpose to have multiple instances of Timing.
As you will also see I don't have any way of performing a "SET" on any of this data, but there are two functions "Begin()" and "Tick()" which both change the values. This is how ALL "setters" should be handled. Basically the "Begin()" function resets all the data and loads in our constants which we CANT set as constants since this is data we retrieve at runtime. Then TICK() updates specific values as time passes in this case so we have fresh up to date information.
If you look far into the code you'll find the values "ResetWindowFrameTime()" and "ElapsedFrameTicks()". Typically I wouldn't do something like this and would have just set the value to public. Since as you'll see I'm retrieving the value and setting the value. This is another form of Set/Get, but it still uses naming that fits the scenario and it uses data from private variables so it didn't make sense to pull another private variable and then multiply it by this rather do the work here and pull the result. There is also NO need to edit the value other then to reset it to the current frame index and then retrieve the elapsed frames. It is used when I open a new window onto my screen so I can know how long I've been viewing this window for and proceed accordingly.