Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to create a setter function in C++

Tags:

I want to write a template function that receives parameter by move or by copy. The most efficient way that I use is:

void setA(A a)
{
   m_a = std::move(a);
}

Here, when we use is

A a;
setA(a);            // <<---- one copy ctor & one move ctor
setA(std::move(a)); // <<---- two move ctors

I recently found out that defining it this way, with two functions:

void setA(A&& a)
{
   m_a = std::move(a);
}
void setA(const A& a)
{
   m_a = a;  // of course we can so "m_a = std::move(a);" too, since it will do nothing
}

Will save a lot!

A a;
setA(a);            // <<---- one copy ctor
setA(std::move(a)); // <<---- one move ctor

This is great! for one parameter... what is the best way to create a function with 10 parameters?!

void setAAndBAndCAndDAndEAndF...()

Any one has any ideas? Thanks!

like image 796
Danny Cohen Avatar asked Oct 23 '20 11:10

Danny Cohen


People also ask

Is it a good practice to use getters and setters?

In Java you should use getters and settersgetters and settersNoun. mutator (plural mutators) That which causes mutation or change. In object-oriented programming, the mutator function changes the value of the field that gives its name.https://en.wiktionary.org › wiki › mutatormutator - Wiktionary : It's considered a good practice because it encapsulates your object's inner state, therefore you can change the internals of the object and change the meaning of the value, doing complex things with it without changing its interface.

How do you create a getter and setter method in C++?

To achieve this, you must declare class variables/attributes as private (cannot be accessed from outside the class). If you want others to read or modify the value of a private member, you can provide public get and set methods.

Why getters and setters are used in C++?

The getter function is used to retrieve the variable value and the settersetterNoun. mutator (plural mutators) That which causes mutation or change. In object-oriented programming, the mutator function changes the value of the field that gives its name.https://en.wiktionary.org › wiki › mutatormutator - Wiktionary function is used to set the variable value. Remember: You can directly access public member variables, but private member variables are not accessible.


1 Answers

The two setter versions setA(A&& a) and setA(const A& a) can be combined into a single one using a forwarding reference (a.k.a. perfect forwarding):

template<typename A>
void setA(A&& a)
{
   m_a = std::forward<A>(a);
}

The compiler will then synthesize either the rvalue- or lvalue-reference version as needed depending on the value category.

This also solves the issue of multi-value setters, as the right one will be synthesized depending on the value category of each parameter.


Having said that, keep in mind that setters are just regular functions; the object is technically already constructed by the time any setter can be called. In case of setA, if A has a non-trivial constructor, then an instance m_a would already have been (default-)constructed and setA would actually have to overwrite it.

That's why in modern C++, the focus is often not so much on move- vs. copy-, but on in-place construction vs. move/copy.

For example:

struct A {
    A(int x) : m_x(x) {}

    int m_x;
};

struct B {
    template<typename T>
    B(T&& a) : m_a(std::forward<T>(a)) {}

    A m_a;
};

int main() {
    B b{ 1 }; // zero copies/moves
}

The standard library also often offers "emplace"-style calls in addition to more traditional "push"/"add"-style calls. For example, vector::emplace takes the arguments needed to construct an element, and constructs one inside the vector, without having to copy or move anything.

like image 198
rustyx Avatar answered Sep 29 '22 09:09

rustyx