Which method is better for implementing get/set? - c++

There are two methos for implementing get/set.
Method 1:
Define get and set separately.
class my_class
{
// ...
};
class main_class
{
public:
my_class get_data() const
{
return m_data;
}
void set_data(my_class value)
{
m_data = value;
}
private:
my_class m_data;
};
Note: In this method get is fast enough: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value
And another method is (Method 2):
Define two get bodies, First const and another non const.
class my_class
{
// ...
};
class main_class
{
public:
const my_class& get_data() const
{
return m_data;
}
my_class& get_data() // Works like set.
{
return m_data;
}
private:
my_class m_data;
};
Using these methods:
void main()
{
main_class cls;
// For method 1.
my_class data;
data = cls.get_data();
cls.set_data(data);
// For method 2.
const my_class data1;
my_class data2;
data1 = cls.get_data(); // const get invoked.
cls.get_data() = data2; // Like set beacuase non const get invoked.
}
My question which of these methods for implementing get/set is better?
Do you know a better method?
Edit:
For answers that believe Method 1 is better, what do you say in below situation:
void main()
{
main_class cls;
// For method 1.
cls.get_data().do_something_else(); // Not effictive for cls, because data losts.
// For method 2.
cls.get_data().do_something_else(); // Effictive for cls.
}

You should always use a reference for any custom classes to pass just the address not the value class. You should also avoid passing back a non-const reference for editing. See below for my recommendations.
class my_class
{
// ...
};
class main_class
{
public:
const my_class & get_data() const
{
return m_data;
}
void set_data(const my_class & data)
{
m_data = data;
}
private:
my_class m_data;
};

I know this won't be a popular answer with C++ purists and before I learned Python, and Ruby I wouldn't have broached the possibility... but... Since the getter and setter you provided doesn't do range checking or special calculations why not make the member public?
class main_class
{
public:
my_class my_data;
}
Sure, you'll lose the const on the getter and won't be guaranteed protection, but you're not guaranteed that anyway because you provide a set function, which modifies the member.

The second one is very bad as it abandons the encapsulation: you can as well just make the corresponding field public, anyone could access it without your object knowing about it. You cannot perform range checks or status updates based on the data being changed etc.

The second one would be a pretty bad choice. The reason for having setters is to be able to control how the member variable is modified by the user. If you just give the user a reference to your member, you lose all control.
So you're pretty much left with the first method. Below are two variations that you might or might not like:
// First Variation
// ---------------
// In this one both the setter and the getter have the same name
// (which is the same as the member they control). To get a
// variable you do `int i = foo.var()` and to set it you do
// `foo.var(6)`.
class Some
{
public:
int var() const {
return var_;
}
void var(int v) {
var_ = v;
}
private:
int var_;
};
// Second Variation
// ----------------
// You can also make the setter return a reference to `this`.
// This allows you to chain setters, which can _sometimes_ be
// more readable but it also has a few disadvantages.
class Employee
{
public:
Employee& salary(double dollars) {
salary_ = dollars;
return *this;
}
Employee& name(const string& n) {
name_ = n;
return *this;
}
private:
double salary_;
std::string name_;
};
// You can now do this...
Employee emp;
emp.name("John Barlick").salary(500.00);
// ... But this can become quite ugly if you chain a large amount
// of setters (you'd then probably have to break the lines in
// order to keep the code readable). It also is (technically)
// less efficient.
// In case you have lots of setters you could probably do this:
// emp.name("John Barlick")
// .salary(500.00)
// .some(787);
// .another('g');

Usually getters/setters are defined:
const my_class& get_data() const
{
return m_data;
}
void set_data(const my_class& _data)
{
m_data = _data;
}

First of all, I think this is not very effective
void set_data(my_class value)
{
m_data = value;
}
You should probably pass by reference
void set_data(const my_class& value)
{
m_data = value;
}
As to which method you should choose, think this way - In your second method you return a reference to your internal object and the user is absolutely free to do anything with it. With the first method, you can control what the user can or cannot do.

While standard getters and settters like method 1 may provide "encapsulation", unless these functions are inlined in a header, they are adding a lot of overhead. For instance, in a tight loop, even if you used references rather than pass-by-value (which then requires a costly memory copy operation), constantly having to add about eight instructions in x86 for every call to a getter/setter in order to setup up its activation record on the stack as well as the function's prologue and epilogue is using up valuable CPU time, and really hurts performance. Since you're getter and setters aren't doing much, you really don't need them.
Method 2 is actually what a number of STL containers do, like std::vector with the operator[], where you overload the same function, but define one for constant operations, and another for non-constant operations ... but again, you're adding unnecessary overhead when you could just publicly access the data member (i.e., it's not like you're some underlying pointers and other memory-managed data-members from us like an STL container). If the function you're passing it to requires a constant reference, it's not going to change the member anyways, so there's really no need to create an interface like this unless you are trying to make a common interface for accessing a member across a host of classes. And if you're doing that, then you should look into a pure virtual base class to define the common interface.

IMHO the second method looks very awkward.

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.

What should I implement, SetMember(const Member&), SetMember(Member) or SetMember(Member&&)?

Let Memeber be a class and let's assume I have no idea if it supports or need move semantics. For all intents and purposes let's say it isn't even specified/written yet. Which case of the SetMember functions should I implement in an Outer class, which has Member as a member?
If Member would not support move, I would do this:
class Member {
public:
Member(Member&&) = delete;
Member& operator=(Member&&) = delete;
};
class Outer {
Member m_member;
public:
void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
};
And if Member would support move, I would do this:
class Member {
public:
Member(Member&&);
Member& operator=(Member&&);
};
class Outer {
Member m_member;
public:
void SetMember(Member o) { m_member = std::move(o.m_member); } // makes a copy if needed
};
But since I do not know if it has move or not, do I need to implement both? Like this:
class Outer {
Member m_member;
public:
void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
void SetMember(Member&& o) { m_member = std::move(o.m_member); } // makes no copy
};
Or should I do this?
class Outer {
Member m_member;
public:
template <class T>
void SetMember(T&& o) { m_member = std::forward<T>(o.m_member); }
};
Why I'm not happy with these two solutions:
In the first solution I see code duplication, which is only needed because I don't know some implementation details of Member namely if it supports move or not.
The second solution leaves me with compilation errors instead of intelli sense errors whenever I try to use SetMember on a wrong type. Also I need a template just because some implementation details of Member.
What's the clean way to handle this situation?
As far as I know passing by value in setters is no longer recommended. At least in case of std::strings when setter is called multiple times, it is highly probable, that the destination variable has enough memory reserved for new value and it's cheaper to just copy the content into already allocated string then create a temporary string and move it.
So no matter if the type is moveable or not it is recommended to pass by const reference and make a copy inside of a setter. If later profiling shows that a temporary is used often as an argument and the cost of copying makes it worth optimizing, an overload for rvalue reference may be added.
See also https://stackoverflow.com/a/26286741/113662

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.

Classes Using their Own Getters/Setters

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.

C++ equivalent for java final member data

First, my latest coding is Java, and I do not want to "write Java in C++".
Here's the deal, I have to create an immutable class. It's fairly simple. The only issue is that getting the initial values is some work. So I cannot simply call initializes to initialize my members.
So what's the best way of creating such a class? And how can I expose my immutable / final properties to the outside world in C++ standards?
here's a sample class:
class Msg {
private:
int _rec_num;
int _seq;
string text;
public:
Msg(const char* buffer) {
// parse the buffer and get our member here...
// ... lots of code
}
// does this look like proper C++?
int get_rec_num() { return _rec_num; }
};
C++ offers some nice mechanisms to make your class immutable. What you must do is:
declare all your public (and maybe protected) methods const
declare (but not define) operator= as private
This will ensure that your objects cannot be modified after they have been created. Now, you can provide access to your now immutable data members anyway you want, using const methods. Your example looks right, provided that you make it const:
int get_rec_num() const { return _rec_num; }
EDIT: Since C++11 you can explicitly delete operator=, rather than just leave it undefined. This explicitly instructs the compiler to not define a default copy assignment operator:
Msg& operator=(const Msg&) = delete;
I'd mark your immutable member as 'const', and assign it a value in your constructor initializer list.
I'd also parse your buffer outside of the class, and pass in the string to the constructor.
Something like this:
class Msg {
private:
int _rec_num;
int _seq;
const std::string text;
public:
Msg(const std::string& str) :
text(str)
{
}
// does this look like proper C++?
int get_rec_num() const { return _rec_num; }
};
// parse the buffer and get our parameter somewhere else
NB:
You should make any member functions that do not change the state of your class internals as 'const'; as this will allow you to call them with const objects.
You should avoid inluding a using std::string in header files; as anyone who includes your header has this 'using' forced upon them.
You're on the right track -- use getters for everything, and without any setters, your class is effectively immutable.
Don't forget some of the corner cases though -- you might want to declare the operator=() method as private and not implement it so someone can't override the object with the default compiler generated assignment operator, etc.
// does this look like proper C++?
int get_rec_num() { return _rec_num; }
You should use
int get_rec_num() const { return _rec_num; }
(see the const which allows to call the member on const objects).
To make a variable immutable you have to use the const key word eg const int _rec_num. Const variables can only be initialised through an initialisation list, which gets called before any code in the constructor. This means that you cannot do any processing in the constructor which sets the const member variables.
You have two ways round this, first you can create another internal class which takes in a buffer and parses it into your variables. Put a const version of this into your MSG class and put this in the initialisation list:
class MsgInner
{
public:
int _rec_num;
Msg(const char* buffer) {
// Your parsing code
}
};
class Msg
{
public:
const MsgInner msg;
Msg(const char* buffer) : msg(buffer)
{ // any other code }
};
This is perhaps not so 'standard', but it's another perspective. Otherwise you can also do it as the other answers have suggested with get methods.
On Finalizers
There is none, you have to emulate it. Either by using a cleanup function or by having all your resources encapsulted in RAII classes. The compiler will place static machinery in your application to call destructors on your RAII classes --i.e., when they go out of scope the resources get released through the destructor.
On Immutability and Initialization
Generally if something is immutable and const-correct the class will have all of its members as const and the only time you get to "write" to them is when the class is initialized. However in your case that might not be possible.
I suggest you gather all your resources and initialize the class (via a non-default constructor with const members) once you have them. The other alternative (which I do not abide) is to have a mutator function that "claims" to be const correct but writes to the const values for a one-time post construction initialization.
First of all, it is possible to initialize the members efficiently and at construction time even if they were declared as const (which is neither necessary nor recommended).
I would still suggest that you split this class into two separate classes (pseudo-code):
// Msg: pure data object; copy constructible but not modifiable.
class Msg
{
public:
Msg(int rec_num, ...)
: rec_num_(rec_num)
...
{}
int rec_num() const
{ return rec_num_; }
...
private:
// prevent copying
Msg& operator=(Msg const&);
private:
int rec_num_;
};
// MsgParser: responsible for parsing the buffer and
// manufacturing Msg's.
class MsgParser
{
public:
static Msg Parse(char const* buffer)
{
... parse ...
return Msg(...);
}
};
// Usage
Msg const msg = MsgParser::Parse(buffer);
This also nicely separates the concerns of holding and parsing the data into separate classes.