Classes Using their Own Getters/Setters - c++

Let's say I have the following class:
class MyClass
{
private:
int Data;
public:
MyClass(int Init)
{
Data = Init;
}
int GetData() const
{
return Data;
}
};
Now, let's say I want to add a method that checks if Data is equal to zero. There are two ways to accomplish this:
bool DataIsZero() const
{
return Data == 0;
}
Or:
bool DataIsZero() const
{
return GetData() == 0;
}
Which is considered better practice? I can see how just using the variable itself might improve readability, but using the getter might make the code easier to maintain.

I don't really like getters/setters for reasons that I won't go into here. They're covered in other questions. However, since you've asked about them, my answer will assume that I use getters/setters; it will not visit all the possible alternatives.
I'd use the getter, for the maintenance reasons to which you allude. Indeed, the abstraction is half the purpose of having the getter in the first place (along with the slightly tighter access control).
If using the variable is more legible than using the getter, then your getter function name is poor and should be reconsidered.
As an aside, it's best to initialise members, not assign them in your constructor body after the fact. In fact, you have to do that with constants, so you might as well start now and remain consistent:
class MyClass
{
private:
int Data;
public:
MyClass(int Init) : Data(Init) {}
int GetData() const {
return Data;
}
};
See how the constructor has changed.

You should use the getter, because if your class moves to a more complex logic in the getter, then you will be insulated from the change. However, if your class provides a public getter, I'd question the logic of creating this method.

It depends.
The former is sufficient for simple classes.
The latter hides the implementation and can support polymorphism, if the method is virtual.

Related

Data hiding worth for simple data containers

In my company, we generate code from XML. The code generator generates header files that contain Messages, and each message contains only data. NOTE we don't do any validation while setting or returning data; also, we don't have to take care of the state, i.e., data x and data in a message are independent; if x is changed, we don't need to change the state of y.
Current header file
class somemessage
{
private:
Field _field;
.......
public:
Field& getfield(){...}
const Field& getfield() const {...}
void setfield(const Field& field){....}
} ;
Do we still need data hiding here if it's only data? Do we require getter and setters in these headers, or can se make it simple as following.
struct somemessage
{
Field field;
};
We can make the message read-only when required using const as following.
void message_consumer(const somemessage& message)
{
message.field = somevalue; // compilation error
}
What are the disadvantages of this approach, and what are the advantages of using accessors and mutators?
If you have the following pattern:
class A {
public:
void SetFoo(const Foo& newFoo) {
f = newFoo;
}
const Foo& GetFoo() const {
return f;
}
protected:
private:
Foo f;
};
That is, you have a getter/setter pair and all they do is have a single return statement and a single assignment expression, then there's no need for the data member to be private and instead just make the data member public and remove the getter/setter pair.
class A {
public:
Foo f;
protected:
private:
};
If your getters/setters do anything else, or are in any way more complicated, then yes, having a getter/setter pair is fine.
In terms of using a struct versus a class, I go with struct if the type is strictly only data; no functions, no constructors. If for whatever reason the data type needs functions, then it should be declared as a class.
Writing a getter like this:
Field& getfield(){...}
is not encapsulation. A user can do this:
Field& decapsulated = x.getField();
and now they have a reference to the private member that they can use to do what they like. All checking and bookkeeping in the setter is futile, because the user does not need it to modify the private member:
decapsulated = some_other_field;
Proper encapsulation has advantages. Though plain old structs with only public members have their place as well. If however all you do is writing boilerplate that does not encapsulate the data, you can leave away the boilerplate. Eventually it is up to you to decide what to use. Encapsulation has lots of advantages, but it is not a must.
Getters returning non-const references can be useful as convenience methods. They can provide easy means for the user to access the class data. Compare for example to std::vector::operator[] or std::vector::at(). Though one should not confuse that with data encapsulation.

Exposing fields from an opaque C struct

I am working with an existing C library (that I can't modify) where some structures have opaque fields that must be accessed through specific setters and getters, like in the following crude example (imagining x is private, even though it's written in C).
struct CObject {
int x;
};
void setCObjectX(CObject* o, int x) {
o->x = x;
}
int getCObjectX(CObject* o) {
return o->x;
}
I am writing classes that privately own these types of structures, kind of like wrappers, albeit more complex. I want to expose the relevant fields in a convenient way. At first, I was simply writing setters and getters wherever necessary. However, I thought of something else, and I wanted to know if there are any downsides to the method. It uses function pointers (std::function) to store the C setter-getter pairs and present them as if directly accessing a field instead of functions.
Here is the generic class I wrote to help define such "fake" fields:
template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}
std::function<void(const T&)> setter;
std::function<T()> getter;
};
It is used by defining an instance in the C++ class and setting up setter and getter with the corresponding C functions:
IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};
Here is a complete, working code for testing.
Are there any disadvantages to using this method? Could it lead to eventual dangerous behaviors or something?
The biggest problem I see with your solution is that std::function objects take space inside each instance of IndirectField inside CPPObject, even when CObject type is the same.
You can fix this problem by making function pointers into template parameters:
template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};
Here is how to use this implementation:
class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};
This approach trades two std::function objects for one CObject* pointer per IndirectField. Unfortunately, storing this pointer is required, because you cannot get it from the context inside the template.
Your modified demo.
Are there any disadvantages to using this method?
There's a few things to highlight in your code:
Your getters & setters, being not part of the class, break encapsulation. (Do you really want to tie yourself permanently to this library?)
Your example shows a massive amount of copying being done; which will be slower than it needs to be. (auto operator()(), operator T() to name but 2).
It's taking up more memory than you need to and adds more compexity than just passing around a Cobject. If you don't want things to know that it's a CObject, then create an abstract class and pass that abstract class around (see below for example).
Could it lead to eventual dangerous behaviors or something?
The breaking of encapsulation will result in x changing from any number of routes; and force other things to know about how it's stored in the object. Which is bad.
The creation of IndirectField Means that every object will have to have getters and setters in this way; which is going to be a maintenance nightmare.
Really I think what you're looking for is something like:
struct xProvider {
virtual int getX() const = 0;
virtual void setX() = 0;
};
struct MyCObject : xProvider {
private:
CObject obj;
public:
int getX() const override {return obj.x;}
CObject& getRawObj() {return obj;}
// etc ...
}
And then you just pass a reference / pointer to an xProvider around.
This will remove the dependence on this external C library; allowing you to replace it with your own test struct or a whole new library if you see fit; without having to re-write all your code using it
in a struct by default (as you post) all the fields are public, so they are accessible by client software. I you want to make them accessible to derived classes (you don't need to reimplement anything if you know the field contract and want to access it in a well defined way) they are made protected. And if you want them to be accessed by nobody, then mark them as private.
If the author of such a software doesn't want the fields to be touched by you, he will mark them as private, and then you'll have nothing to do, but to adapt to this behaviour. Failing to do will give you bad consequences.
Suppose you make a field that is modified with a set_myField() method, that calls a list of listeners anytime you make a change. If you bypass the method accessing function, all the listeners (many of them of unknown origin) will be bypassed and won't be notified of the field change. This is quite common in object programming, so you must obey the rules the authors impose to you.

Const reference field as readonly property in C++ class

Is it good to use a const reference field as a readonly getter in C++ classes?
I mean, does this code meet good practices?
class check{
private:
int _x;
public:
const int& x = _x;
void setX(int v){
_x = v;
}
};
It is working very much like C# properties, IMHO, and very easy and clean in class usage code:
check s;
int i;
std::cin >> i;
s.setX(i);
std::cout << s.x << '\n';
s.setX(7);
// s.x = i; // Error
std::cout<<s.x<<'\n';
do this code meet good practices?
Not really, since it introduces unnecessary complexity and space overhead.
Moreover, you wouldn't be able to perform runtime checks and/or assertions, regardless of the value being accessed.
Furthermore, what happens with the lifetime and semantics?
Try assigning one check in your code to another and see what happens. The assignment is ill-formed because the class is non-assignable. You should provide a copy and move constructor to take care of the reference, so that it won't refer to the old object's data member.
Better use _x directly and have a straightforward inline getter function.
PS: C#-like properties in native C++?
Generally, it is not a good practice.
imho, and very easy and clean in class usage code.
Why should that be clearer and easier?
You introduce another variable member (useless overhead). (Generally, the reference will be implemented as an additional member pointer).
It makes the code harder to maintain. You are actually creating dependencies among variable members.
It makes problem in the assignment and in the copy operations. How is copy operation supposed to work?
The "classic" approach is sound clearer by me, e.g.:
class Foo {
public:
void set_num(int value) noexcept { m_num = value; }
int get_num() const noexcept { return m_num; }
void set_string(std::string value) noexcept {
m_str = std::move(value);
}
const std::string& get_string() const noexcept {
return m_str;
}
private:
int m_num;
std::string m_str;
};
From a performances point of view, this approach should be preferred.
Timing complexity: call get_variable on an inline function does not introduce more overhead than your "reference approach". Moreover, it is highly optimizable by the compiler (because of straightforward of the code).
Space complexity: it does not introduce additional data member.
What you propose is in general a bad idea:
You can't implement the property by doing any processing (e.g. with a getter you can store co-ordinates using [x,y] and later decide to change the implementation to use [angle,radius] while keeping the same public interface).
Using a const member variable involves space overhead, and doesn't give you any performance advantage compared with an inline getter.
It's not idiomatic.
Once you've published your class, and other people start using it, you're stuck with it: it's too late to change it to use a method instead.
If your intention with properties is to make the code more succinct, you don't have to use the words "get" and "set" in your function names; that's an old-fashioned practice. You can use the actual name of the "property" as the function name, and you can overload the getter and setter:
class Cheque {
public:
int x() const {
return x_;
}
Cheque & x(int newX) {
x_ = newX;
return *this;
}
private:
int x_;
}
// Usage:
// int amt = myCheque.x(1234);
// Cheque c = Cheque().x(123);
Returning *this as in the above code enables you to use method chaining; a way of implementing the Fluent interface idiom.
When C# compiles a propery it gets compiled into a getter and a setter function.
Here's some C# code that proves this fact:
using System;
namespace Reflect
{
class Program
{
class X
{
public int Prop { get; set; }
}
static void Main(string[] args)
{
var type = typeof(X);
foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
}
Console.ReadKey();
}
}
}
Your output should be:
get_Prop
set_Prop
ToString
Equals
GetHashCode
GetType
get_Prop is the function that implements the getter.
set_Prop is the function that implements the setter.
So even if what you're doing looks similar, it's not the same at all.
Frankly almost everything you could do to try to emulate 'property syntax' in C++ will fall down in one way or another. Most solutions will either cost you memory or it'll have some limitation that makes it more cumbersome than useful.
Just learn to live with getters and setters.
Getters and setters are good practice.
They're short, they're simple, they're flexible, they're typically good candidates for inlining, everyone understands what they do et cetera.

Access attributes or use getter methods?

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
}
}

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).