Access attributes or use getter methods? - c++

As a C++ beginner, I didn't thought about that much until now, but if I want to access an attribute from inside a class itself, should I access the attribute directly or use a getter function?
class foo
{
public:
int getVal();
void bar();
private:
int val;
}
foo::bar()
{
int val = this->getVal();
// or
int val2 = this->val;
}
I would like to know that for
a) what is better design and (more importantly for me)
b) any performance differences (maybe because of the overhead calling the function)?
I normally use the getter method even inside the class in case I ever want to rename the attribute. But now I'm writing a method, which will access the attribute quite (very) often.

It depends. Getters may have synchronization and if called from a method that is already holding the lock may deadlock the application. Or, on the contrary, getters may count/log access to the resource. Or even, the class may be an interface on the byte buffer and getters/setters dynamically unmarshal/marshal the wire data, in which case calling getters and setters is unavoidable.
The only universal rule - be consistent across the code base and try to not overcomplicate the design.

Inside the class always use the attribute itself. The reason you have a getter is to make a certain value available to other classes. Be careful with automatically making getters for every attribute you use. It is considered bad design to expose the inner workings of a class. Sometimes it makes sense to make an attribute available, sometimes it is just for internal use and other classes have no business inspecting them.
If you like to know more about this google "getters setters evil" Some of the articles you may find are quite extreme but they will explain why they feel that way.

I disagree with #user3535256. Getters and setters should also be used inside private class functions. The idea behind getters and setters is to make code changes nice and easy. #StanE think of a situation where you're using your class member variable without getter functions and after some time you'd like to change the name to be more meaningful. This example forces you to change the member name in each place it's used. In case of using getter method for your variable only class getter function will be affected by this code change.

Basically, getter and setters are used to hide complexity, or better saying, to abstract details from out of a class. So they are not mandatory for using inside a class.
Simply I can say, if you don't have a getter, you don't need to make that, for using inside of the class.
But if you have a getter, you should always use that, whether inside or outside of the class, as you might have applied some logic to the raw value inside getter.

This depends on the internals of your class. Suppose you have a simple class that holds a value and you want to count how often that value was accessed but there are different getter methods (I have to admit it is a quite contrived example). Instead of doing the bookkeeping in each of the methods it is easier to do it only once and use the getter also inside the class:
class CountedValue{
private:
int value;
int counter;
public:
CountedValue() : value(0),counter(0) {}
int getValue() const {
counter++;
return value;
}
int getMinusValue() const {
return - getValue();
}
// ... possibly more methods to retrieve the value
int getCounter() const { return counter;}
}
Actually with setters the benefit of using them also inside the class becomes more evident. You usually want to do bookkeeping and define the invariants of a member only once and not each time it can change.
For example:
class Rational {
private:
int numerator;
int denominator;
public:
void setNumerator(int n) { numerator = n; }
void setDenominator(int d) {
assert(d != 0 && "division by zero");
denominator = d;
}
void set(int n, int d) {
setNumerator(n);
setDenominator(n); // no need to check for 0 again
}
}

Related

Is it possible to override member access operators to detect when any member variable is modified?

Say I have:
struct foo{
int bar;
int baz;
...
bool flag;
}
Can an access operator -> or . be overridden to detect if bar or any other member variable is modified ?
EDIT:
The purpose is if I have many member variables and any of them is changed, I have a quick way of setting a flag, instead of using setters to encapsulate all the variables, making the code verbose.
Your approach is flawed because even if you override access operators you will not catch pointers writing the actual memory.
If most of the variables have the same type you can use an enum for flags and a single function to set or get a specific variable.
For example:
private:
int bar;
int baz;
public:
enum IntVariables { varBar, varBaz };
bool flag;
void setVariable(int varId, int value) {
flag = true;
if (varId == varBar)
bar = value;
else if (varId == varBaz)
baz = value;
}
I considered the following approach:
Just use a wrapper class that can have any data type, but implement all operations. In this same wrapper class override operators, and use the wrapper class in other class that require any modifications of member variables to be detected.
template <class T>
class wrapper {
private:
T var;
... .. ...
public:
T doSomethingToVar(T arg);
... .. ...
//Wherever the variable is modified send out a notification to whomever needs to detect the changes.
};
Pros:
When declaring variables in whichever class needs to detect modification of variables, it is easy to declare using the wrapper, without much additional code.
To ensure modifications are detected, need to implement functions / getters / setters / overload operators to detect modifications. This is tricky, and requires some thought.
Cons:
Tricky to implement a general purpose wrapper that can detect all modifications, since complex types can have functions that modify themselves in ways one is not aware of.
Notes:
How to ensure that every method of a class calls some other method first?
This answer is a work in progress, and I think it may be useful to others and maybe just cool to know about eventually, so open to comments. Will keep updating.
Update:
While writing out the above answer, I considered a different approach, of shifting responsibility onto the member variable classes:
class DetectChanges{
void onDetectChanges(){
//This function should be called by all implementing classes when the class has changes.
}
Can make it a design choice that all member variables inherit from DetectChanges.
The above two approaches are what I'm considering now. Not a solution yet, but thought I would put it out for comments and see if eventually we can figure something out.
}

Modifying private object properties through method which returns reference

I'm curious if that's proper way of assignement
class Foo {
int x_;
public:
int & x() {
return x_;
}
};
My teacher is making assignement like that: obj.x() = 5;
But IMO that's not the proper way of doing it, its not obvious and it would be better to use setter here. Is that violation of clear and clean code ? If we take rule that we should read the code like a book that code is bad, am I right ? Can anyone tell me if am I right ? :)
IMO, this code is not a good practice in terms of evolution. If you need to provide some changes checking, formatting, you have to refactor your class API which can become a problem with time.
Having set_x() would be a way cleaner. Moreover, it will allow you to have checking mechanics in your setter.
a proper getter get_x() or x() could also apply some logic (format, anything...) before returning. In your case, you should return int instead of int& since setter should be used for modification (no direct modification allowed).
And truly speaking, this code doesn't really make sense... it returns a reference on a property making it fully modifiable. Why not having directly a public property then ? And avoid creating an additional method ?
Do you want control or not on your data? If you think so, then you probably want a proper getter and setter. If not, you probably don't need a method, just make it public.
To conclude, I would say you are right, because the way you see it would make it better over the time, prone to non-breaking change, better to read.
As the UNIX philosophy mentions : "Rule of Clarity: Clarity is better than cleverness."
Assuming that x() happens to be public (or protected) member the function effectively exposes an implementation: the is an int held somewhere. Whether that is good or bad depends on context and as it stands there is very little context.
For example, if x() were actually spelled operator[](Key key) and part of a container class with subscript operator like std::vector<T> (in which case Key would really be std::size_t) or std::map<Key, Value> the use of returning a [non-const] reference is quite reasonable.
On the other hand, if the advice is to have such functions for essentially all members in a class, it is a rather bad idea as this access essentially allows uncontrolled access to the class's state. Having access functions for all members is generally and indication that there is no abstraction, too: having setters/getters for members tends to be an indication that the class is actually just an aggregate of values and a struct with all public members would likely serve the purpose as well, if not better. Actual abstractions where access to the data matters tend to expose an interface which is independent of its actual representation.
In this example, the effect of returning a (non-const) reference is the same as if you made the variable public. Any encapsulation is broken. However, that is not a bad thing by default. A case where this can help a lot is when the variable is part of a complicated structure and you want to provide an easy interface to that variable. For example
class Foo {
std::vector<std::list<std::pair<int,int>>> values;
public:
int& getFirstAt(int i){
return values[i].[0].first;
}
};
Now you have an easy access to the first element of the first element at position i and dont need to write the full expression every time.
Or your class might use some container internally, but what container it is should be a private detail, then instead of exposing the full container, you could expose references to the elements:
class Bar {
std::vector<int> values; // vector is private!!
public:
int& at(int i){ // accessing elements is public
return values.at(i);
}
};
In general such a code confuses readers.
obj.x() = 5;
However it is not rare to meet for example the following code
std::vector<int> v = { 1, 0 };
v.back() = 2;
It is a drawback of the C++ language.
In C# this drawback was avoided by introducing properties.
As for this particular example it would be better to use a getter and a setter.
For example
class Foo {
int x_;
public:
int get_value() const { return x_; }
void set_value( int value ) { x_ = value; }
};
In this case the interface can be kept while the realization can be changed.

Proper design of member setters/getters in a C++ class

The usual way of designing setters and getters for a class member is the following
class QNumber
{
public:
void setNumber(unsigned int xNumber){ this->mValue = xNumber; };
unsigned int getNumber(void) const { return this->mValue; };
private:
unsigned int mValue;
}
If the member is another class (e.g. QRational as opposed to unsigned int), then the getter would be better returning a reference, in terms of performance.
So the modified design would be
class QNumber
{
public:
const QRational & value(void) const { return mValue;} // getter
QRational & value(void) { return mValue;} // 'setter'
private:
QRational mValue;
}
My question is - isn't there something potentially wrong with the latter approach? I have not seen it much in other people's code and to me, it seems more elegant than set/get method.
Many thanks,
Daniel
The point of getters and setters is to separate the interface from the implementation. If you return a reference, it has to point somewhere in the implementation. Now if you change the implementation, you'll have to start returning by value instead.
Personally I prefer public nonstatic members when the need for anything else is unlikely. Reference-semantic getters and setters provide the worst of both worlds. (I am working on a proposal to improve them, though.)
In addition to Potatoswatter's answer, please note one more point.
You second design provokes usage in the following form:
QRational& r = number.value();
// or
const QRational& r = number.value();
thus the user retains the reference to your inner object. It will be somewhat more difficult to manage in case your number object can be destroyed or moved while r is still there. This does not even depend on whether the const or non-const method is used.
The first design does not expose such problems.
At least in my opinion, if that member acts like an unsigned int (e.g., allows assignment to/from an unsigned int), and you're really sure this class should support direct manipulation of that member (i.e., it should have a "getter" and "setter" at all), then you should at least make access to it clean, rather than requiring other code to be written around that implementation detail. To avoid that, you should define how the type of this object differs from a plain unsigned int, then implement that behavior in a class that defines that type properly and directly.
class QNumber { // bad name--looks like a Qt class name
unsigned int value;
public:
QNumber(unsigned int value = 0) : value(value) {}
QNumber &operator=(unsigned int val) { value = val; return *this; }
operator unsigned int() { return value; }
};
With this, client code can be readable--instead of ugliness like x.SetNumber(2); or x.SetNumber() = 2; you just use x = 2;. This also avoids all sorts of lifetime issues that arise when you let a client get a pointer or reference to the class' internals (which you should generally avoid).

Difference between Class A and class Class1

I am trying to do this C++ tutorial. I am a beginner in C++ programming. I don't get why they use setValue and getValue in class Class1 and not setClass1. In the other tutorial they use setA and getA in the class class Class1. Here are the codes:
class Class1 {
int i;
public:
void setValue( int value ) { i = value; }
int getValue() { return i; }
};
the second code is:
class A{
int ia;
public:// accessor method because they are used to access a private date member
void setA ( const int a);
int getA ()const;
int getA ();
};
Please help...
The names are arbitrary, you can use any function names you wish (subject to language rules, of course).
However, although you can use xyzzy() and plugh() as getter and setter, it's not really a good idea.
You should use something that indicates the intent of the call, such as getTemperature() or setVelocity(). And these don't even have to map one-to-one to internal fields since encapsulation means the internal details should not be exposed.
By that, I mean you may have a getTemperatureC() for returning the temperature in Celsius even though the internal field is stored as Kelvins:
double getTemperatureC(void) { return kelvins - 273.15; }
void setTemperatureC(double t) { kelvins = t + 273.15; }
(or a getter/setter may use arbitrarily complex calculations).
Using getA() for a class A may well cause you trouble when you create class B to inherit from A but this is outside the scope of the language. But it's good programming practice to follow the guideline above (functions should indicate intent rather than internals).
I was confused on why they use the same name in get and set with the class name, and different get and set name on the other class. Will the set and get names affect the code?
The answer is No.
getter and setter are usually called accessor and mutators in a class. They are just member functions named according to some convention, easy for people who read the code to understand the purpose of those functions, so it is like common sense to name those member function starting with get if you try to access the member variables and starting with set if you try to change some member variables. The names can be any valid identifier.
So setValue or setA are just identifiers for those member functions. It will not affect the code.
Meanwhile, different class can have the same named getter or setters since those function names are in different class scope.

Conventions for accessor methods (getters and setters) in C++

Several questions about accessor methods in C++ have been asked on SO, but none was able satisfy my curiosity on the issue.
I try to avoid accessors whenever possible, because, like Stroustrup and other famous programmers, I consider a class with many of them a sign of bad OO. In C++, I can in most cases add more responsibility to a class or use the friend keyword to avoid them. Yet in some cases, you really need access to specific class members.
There are several possibilities:
1. Don't use accessors at all
We can just make the respective member variables public. This is a no-go in Java, but seems to be OK with the C++ community. However, I'm a bit worried about cases were an explicit copy or a read-only (const) reference to an object should be returned, is that exaggerated?
2. Use Java-style get/set methods
I'm not sure if it's from Java at all, but I mean this:
int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount
3. Use objective C-style get/set methods
This is a bit weird, but apparently increasingly common:
int amount(); // Returns the amount
void amount(int amount); // Sets the amount
In order for that to work, you will have to find a different name for your member variable. Some people append an underscore, others prepend "m_". I don't like either.
Which style do you use and why?
From my perspective as sitting with 4 million lines of C++ code (and that's just one project) from a maintenance perspective I would say:
It's ok to not use getters/setters if members are immutable (i.e. const) or simple with no dependencies (like a point class with members X and Y).
If member is private only it's also ok to skip getters/setters. I also count members of internal pimpl-classes as private if the .cpp unit is smallish.
If member is public or protected (protected is just as bad as public) and non-const, non-simple or has dependencies then use getters/setters.
As a maintenance guy my main reason for wanting to have getters/setters is because then I have a place to put break points / logging / something else.
I prefer the style of alternative 2. as that's more searchable (a key component in writing maintainable code).
2) is the best IMO, because it makes your intentions clearest. set_amount(10) is more meaningful than amount(10), and as a nice side effect allows a member named amount.
Public variables is usually a bad idea, because there's no encapsulation. Suppose you need to update a cache or refresh a window when a variable is updated? Too bad if your variables are public. If you have a set method, you can add it there.
I never use this style. Because it can limit the future of your class design and explicit geters or setters are just as efficient with a good compilers.
Of course, in reality inline explicit getters or setters create just as much underlying dependency on the class implementation. THey just reduce semantic dependency. You still have to recompile everything if you change them.
This is my default style when I use accessor methods.
This style seems too 'clever' to me. I do use it on rare occasions, but only in cases where I really want the accessor to feel as much as possible like a variable.
I do think there is a case for simple bags of variables with possibly a constructor to make sure they're all initialized to something sane. When I do this, I simply make it a struct and leave it all public.
That is a good style if we just want to represent pure data.
I don't like it :) because get_/set_ is really unnecessary when we can overload them in C++.
STL uses this style, such as std::streamString::str and std::ios_base::flags, except when it should be avoided! when? When method's name conflicts with other type's name, then get_/set_ style is used, such as std::string::get_allocator because of std::allocator.
In general, I feel that it is not a good idea to have too many getters and setters being used by too many entities in the system. It is just an indication of a bad design or wrong encapsulation.
Having said that, if such a design needs to be refactored, and the source code is available, I would prefer to use the Visitor Design pattern. The reason is:
a. It gives a class an opportunity to
decide whom to allow access to its
private state
b. It gives a class an
opportunity to decide what access to
allow to each of the entities who are
interested in its private state
c. It
clearly documents such exteral access
via a clear class interface
Basic idea is:
a) Redesign if possible else,
b)
Refactor such that
All access to class state is via a well known individualistic
interface
It should be possible to configure some kind of do's and don'ts
to each such interface, e.g. all
access from external entity GOOD
should be allowed, all access from
external entity BAD should be
disallowed, and external entity OK
should be allowed to get but not set (for example)
I would not exclude accessors from use. May for some POD structures, but I consider them a good thing (some accessors might have additional logic, too).
It doesn't realy matters the naming convention, if you are consistent in your code. If you are using several third party libraries, they might use different naming conventions anyway. So it is a matter of taste.
I've seen the idealization of classes instead of integral types to refer to meaningful data.
Something like this below is generally not making good use of C++ properties:
struct particle {
float mass;
float acceleration;
float velocity;
} p;
Why? Because the result of p.mass*p.acceleration is a float and not force as expected.
The definition of classes to designate a purpose (even if it's a value, like amount mentioned earlier) makes more sense, and allow us to do something like:
struct amount
{
int value;
amount() : value( 0 ) {}
amount( int value0 ) : value( value0 ) {}
operator int()& { return value; }
operator int()const& { return value; }
amount& operator = ( int const newvalue )
{
value = newvalue;
return *this;
}
};
You can access the value in amount implicitly by the operator int. Furthermore:
struct wage
{
amount balance;
operator amount()& { return balance; }
operator amount()const& { return balance; }
wage& operator = ( amount const& newbalance )
{
balance = newbalance;
return *this;
}
};
Getter/Setter usage:
void wage_test()
{
wage worker;
(amount&)worker = 100; // if you like this, can remove = operator
worker = amount(105); // an alternative if the first one is too weird
int value = (amount)worker; // getting amount is more clear
}
This is a different approach, doesn't mean it's good or bad, but different.
An additional possibility could be :
int& amount();
I'm not sure I would recommend it, but it has the advantage that the unusual notation can refrain users to modify data.
str.length() = 5; // Ok string is a very bad example :)
Sometimes it is maybe just the good choice to make:
image(point) = 255;
Another possibility again, use functional notation to modify the object.
edit::change_amount(obj, val)
This way dangerous/editing function can be pulled away in a separate namespace with it's own documentation. This one seems to come naturally with generic programming.
Let me tell you about one additional possiblity, which seems the most conscise.
Need to read & modify
Simply declare that variable public:
class Worker {
public:
int wage = 5000;
}
worker.wage = 8000;
cout << worker.wage << endl;
Need just to read
class Worker {
int _wage = 5000;
public:
inline int wage() {
return _wage;
}
}
worker.wage = 8000; // error !!
cout << worker.wage() << endl;
The downside of this approach is that you need to change all the calling code (add parentheses, that is) when you want to change the access pattern.
variation on #3, i'm told this could be 'fluent' style
class foo {
private: int bar;
private: int narf;
public: foo & bar(int);
public: int bar();
public: foo & narf(int);
public: int narf();
};
//multi set (get is as expected)
foo f; f.bar(2).narf(3);