0

I was wondering why it is needed to use const A& in this situation, Why can't I use just A&? according to what I read is because it specified that it won't change the object. Is there any other reason? I would like a better explanation.

Code:

#include<iostream>
#include<set>

class A{
public:
    int x;
    A(int x=0): x{x} {std::cout<<"Construct"<<std::endl;};
    A(const A& rhs) {x=rhs.x;std::cout<<"Copy"<<std::endl;}
};

bool operator < (const A& lhs,const A& rhs) {return lhs.x<rhs.x;}

int main(){
    std::set<A> Set;
    A a(10);
    Set.insert(a);
    Set.emplace(10);
    return 0;
}
3
  • do you mean in the constructor? Commented Mar 23, 2022 at 2:36
  • @pm100 yes, in the constructor. Commented Mar 23, 2022 at 2:47
  • 1
    If creating a copy of an object (e.g. defining and initialising b as a copy of a, via A b(a);) one often does not expect the logical state of a (the object being copied) to change. Qualifying the argument of the copy constructor as const communicates that is, indeed, the case. Among other things, this allows creating a temporary (an unnamed object within an expression, and copying the temporary). If it does make sense for the state of a to change, the const can be omitted - among other things, that does prevent copying of a temporary. Commented Mar 23, 2022 at 2:55

1 Answer 1

3

A& is an lvalue reference, which means it can change the thing it's looking at. With

A(A& rhs)

you can call it like

int x = 10;
A a(x);

And then any changes to rhs in the constructor will change the actual variable x. And that's fine. But when you do

A a(10);

That's a problem. Because if someone changes rhs in the constructor, that means we have to "change" the number 10, and that's not really even a meaningful thing to do. 10 += 1 is nonsense in C++, for instance.

const A& is a guarantee that we aren't going to change the thing being pointed to, so it becomes safe to pass a temporary value like 10 to the function.

If we knew it was always a "small" datatype like int, we might take it by value, but we don't want to take an A as argument, since some types (like vectors) can be expensive to copy, and others (like unique_ptr) are outright impossible to copy.

Depending on your use case, you can consider using A&&, an rvalue reference. This is useful if you intend to move the value into the class you're constructing, rather than make a copy of it. You can read more about move semantics on this question, but if you're just starting out in C++, it's probably best to stay away from rvalue references. It is good to be aware that they exist, though.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.