Travis
Travis

Reputation: 31

C++ Passing Structures by Const Reference

I know that passing structures by const reference is more efficient than value, but what if I want to make changes to the value being passed temporarily, rather, for the remainder of the function's life. Doesn't const prevent any changes being made to the structure? In other words, how can I make temporary changes to the structure in a function while still passing it by const reference?

Upvotes: 1

Views: 3271

Answers (4)

Vishal Gupta
Vishal Gupta

Reputation: 244

If you are going to change only one or two member of structures, In that case It's better if you make the copy of those structure members instead of copying all the structure. Else You can use pass by value or you can make a local copy. But in some cases copy is expensive.

Upvotes: 0

Rohit Chatterjee
Rohit Chatterjee

Reputation: 3107

The reason you need to make a copy is that when you receive a const reference, you are receiving the ability to look at data without being able to modify it. If you want to modify parts of this data temporarily within a function, you have to ask yourself where these modified values are going to be stored. Since you don't own the original memory locations, you need to make a copy for this purpose.

You have two options for how to make this copy:

  1. Pass the data to the function by value (the compiler will create a copy for you)
  2. Receive a reference and make a copy within the function manually

If you want to maintain the original values of the data for whatever reason, choose Option 2. For example, to track changes in the object:

void f(const S & originalData)
{
    S copy(originalData);
    // modify the copy...

    int delta = copy.someVal - originalData.someVal;
    // etc..
}

If you don't need to do this, go with Option 1! You will have only one variable name to keep track of, and you won't accidentally make a modification to your local copy and then read the wrong value from the original data:

void f(const S & originalData)
{
    S myData(originalData);

    // do stuff...
    myData.field += 100;

    // want to access the modified field but accidentally read the original!
    doSomethingImportant(originalData.field);
}

If you have a long messy function, this could very well happen.

So: prefer Option 1 unless you want to track changes.

Upvotes: 0

davidhigh
davidhigh

Reputation: 15518

If you are really keen you can also use const_cast:

void foo(my_very_expensive_to_copy_type const& bar)
{
    auto a = const_cast<my_very_expensive_to_copy_type&>(bar);

    // (i)   change the object
    // (ii)  do something else    
    // (iii) restore changes    
}

However, that doesn't really make sense. If you want to change it, you should rather pass it either by non-const reference, or by value. In the latter case you also don't need to restore the original state, but the copy might be expensive.

Upvotes: 0

mp_
mp_

Reputation: 695

You can make a local copy, but in that case it's better (less verbose) to just pass by value.

Upvotes: 4

Related Questions