Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use a function rather than a reference to member?

I was just testing looking through some code and noticed something similar to:

template<typename T> class example{     public:         example(T t): m_value{t}{}          const T &value = m_value;      private:         T m_value; }; 

I haven't seen this before. Almost every API or library I've used before defines a function that returns a member variable like so, and not a constant reference to it:

template<typename T> class example{     public:         example(T t): m_value{t}{}          const T &value() const{             return m_value;         }      private:         T m_value; }; 

Why is the first way less common? What are the disadvantages?

like image 366
RamblingMad Avatar asked Apr 22 '14 23:04

RamblingMad


People also ask

When should a function be a member function?

One way to look at this is this: If a function manipulates an object's inner state, then that's a good indication that this function should probably be a member function. If a function uses an object without changing its inner state, then that's a good indication that this function probably should be a free function.

How arguments are passed to a function using references?

The call by reference method of passing arguments to a function copies the reference of an argument into the formal parameter. Inside the function, the reference is used to access the actual argument used in the call. This means that changes made to the parameter affect the passed argument.

What will happen while using pass by reference?

Pass-by-reference means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the argument by using its reference passed in.

When should you pass by reference C++?

If you recall, using pass by reference allows us to effectively “pass” the reference of a variable in the calling function to whatever is in the function being called. The called function gets the ability to modify the value of the argument by passing in its reference.


2 Answers

There are a few reasons why (inline) functions that return an appropriate reference are better:

  1. A reference will require memory (typically the same amount as a pointer) in each object

  2. References typically have the same alignment as pointers, thus causing the surrounding object to potentially require a higher alignment and thus wasting even more memory

  3. Initializing a reference requires (a minuscule amount of) time

  4. Having a member field of reference type will disable the default copy and move assignment operators since references are not reseatable

  5. Having a member field of reference type will cause the automatically generated default copy and move constructors to be incorrect, since they will now contain references to the members of other objects

  6. Functions can do additional checking like verifying invariants in debug builds

Be aware that due to inlining, the function will usually not incur any extra costs beyond a potentially slightly larger binary.

like image 116
gha.st Avatar answered Oct 11 '22 07:10

gha.st


Encapsulation.

For Object-Oriented Programming purists, m_value is an implementation detail. Consumers of class example should be able to use a single reliable interface to access value() and shouldn't be dependent on how example happens to determine it. A future version of example (or an complicated template specialization) might want to use caching or logging before returning a value(); or it might need to calculate value() on the fly because of memory constraints.

If you don't use an accessor function originally, everything that uses example might have to change if you change your mind later. And that can introduce all kinds of waste and bugs. It's easier to just abstract it one level further by providing an accessor like value().

On the other hand, some people just aren't as rigid about those kinds of OOP principles and just like to write code that's efficient and legible, dealing with refactoring when it happens.

like image 30
adpalumbo Avatar answered Oct 11 '22 07:10

adpalumbo