Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About using returned references

Tags:

c++

reference

I'm having some trouble trying to understand proper usage of returned references in C++. I have a class with a "big" object inside. I want to be able to use this object outside the class "read only" mode by returning a const reference to it.

The problem is I don't quite understand when objects get copied and when they don't.

Most of the questions about returning references where about returning objects allocating on the stack, which is not my particular problem, so I've prepared this little example:

class foo {
  int a;

public:
  foo() {
    a = 3;
  }

  int& getInt() {
    return a;
  }

  const int& useInt() {
    return a;
  }

  void print() {
    cout << "Inside class: a = " << a << endl;
  }
};

int main() {
  foo foo1;

  int& goodRef = foo1.getInt();
  int badRef = foo1.getInt();

  goodRef = 4;
  badRef = 5;

  foo1.print();

  foo1.getInt() = 6;
  foo1.print();

  int usingIt = 10*foo1.useInt();
}

What I understand is:

  • In int& goodRef = foo1.getInt(); nothing is copied, only the class owned a exists.
  • In int badRef = foo1.getInt(); badRef is a copy of a, so there are 2 separate objects, a and badRef.

So depending on what type of object catches the return value it is copied or it is not, so my question is:

When I use the reference like in int usingIt = 10*foo1.useInt(); is it copied and then used to multiply or only the value inside the class is used?

In this example it doesn't matter since it is only an int, but if it was a big object it would be a big deal.

Thanks!

Edit: Thanks to all the answers, but I get that having such methods inside a class is bad, I only put them for the sake of the example.

My actual class has a bunch of objects inside and an interface and bla bla, but one particular object is a glm::mat4. What i want is to be able to write something like glm::vec4 finalVec = foo1.getMatrix() * vec. But I dont want the whole matrix to be copied and then multiplied, rather I want to use the matrix that is already inside my class to perform the multiplication and at the same time not let the user modify it. I supposed something similar to useInt but with the mat4 would work but I wasn't sure and that's why I asked the question.

The glm specificatioon is very confuse for me, but I think the operator * is described as:

glm::mat4 operator* (glm::mat4 const & m, glm::vec4 const & v);

like image 830
Hydn Avatar asked Nov 22 '25 19:11

Hydn


1 Answers

In your example int usingIt = 10*foo1.useInt();, the operator*(), depending on it's argument signature and internals, could cause a copy of your object to take place, at which point it would then be assigned (rather than copied again) into the value of usingIt. If your object was an aggregate or class object type, the copy using the object type's assignment operator would typically be elided using a compiler optimization step.

In general, anytime you are copying a l-value reference type (i.e., T& or const T&) to an aggregate or class object to a non-reference type (i.e., type T), a copy constructor, constructor, assignment operator, or conversion operator is invoked on the returned reference to the object.

like image 166
Jason Avatar answered Nov 25 '25 09:11

Jason



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!