Copy constructor, why in turn function values

Suppose i:

class A { A(A& foo){ ..... } A& operator=(const A& p) { } } ... A lol; ... A wow(...) { return lol; } ... ... A stick; stick = wow(...); 

Then I will get a compilation error in the last line. But if I add "const" to "A &", then that's fine.

I want to know why. Where exactly is the problem? I do not understand why this should be const.

Language: C ++

I edited ... I think we will change its meaning. This gives an error.

+4
source share
5 answers

The following code compiles perfectly with Comeau and VC9:

 class A { public: A() {} A(A&){} }; A lol; A wow() { return lol; } int main() { A stick; stick = wow(); return 0; } 

If this does not compile with your compiler, I suspect your compiler will be broken. If this is the case, then that means you have to paste the real code instead of providing a snippet that doesn't look like the problem you are seeing.

+1
source

Calling wow results in a temporary object, r-value. R values ​​cannot be assigned to non-constant references. Since your copy constructor accepts non-constant references, you cannot directly pass the result of a wow call. This is why adding const fixes the problem. Now the copy constructor accepts references to const, whose r-values ​​correspond only to a fine.

Most likely, your copy constructor does not change the object that it copies, so the parameter should be passed using const-reference. This is how copy constructors work, except in specific documented circumstances.

But, as sbi points out in his answer, this copy constructor should not be called at all. Therefore, although this is all the case, it probably has nothing to do with your problem. If there is no compiler error. Perhaps your compiler sees a two-stage construction and decided that it cuts out the average person by converting A stick; stick = wow(); A stick; stick = wow(); in A stick = wow(); . But this will be a mistake, as evidenced by the fact that it creates a compilation error from a completely legal code. But without real code it is impossible to say what is really happening. There must be several other errors before having problems with your copy constructor.

+1
source

I believe that the problem you are talking about is similar to:

C ++, lifetime of anonymous (unnamed) variables

where the significant point is that in C ++ anonymous temporary files cannot be transferred by reference, but only by const link.

+1
source

Not reproducible. Do you miss the default constructor or forgot to make public constructors?

See http://www.ideone.com/nPsHj .

(Note that the copy constructor can accept the cv A& argument with any constant-volatile combination, plus some default arguments. See & sect; [class.copy] / 2 in the C ++ standard.)


Edit: Interestingly, g ++ - 4.3 (ideone) and 4.5 (with the -pedantic flag) do not have a compilation error, but g ++ - 4.2 complain:

 x.cpp: In function 'int main()': x.cpp:19: error: no matching function for call to 'A::A(A)' x.cpp:7: note: candidates are: A::A(A&) 
0
source

This function:

 A wow(...) { ... } 

returns an object by value.
This means that it is copied back to the point where the function was called.

This line:

 stick = wow(...); 

Is a stick copy made?
The value copied to the stick is the value copied back from the wow () function.
But remember that the result of calling wow () is a temporary object (it was copied back from wow (), but is not yet in a variable).

So now we look at the copy constructor for A:

 A(A& foo){ ..... } 

You are trying to pass a temporary object to a reference parameter. It is forbidden. A temporary object can only be bound to a constant reference. There are two solutions to the problem:

1) Use the const link.
2) Navigate by value to the copy constructor.

Unfortunately, if you use solution (2), you get a bit stuck as it becomes a cyclical dependency. Passing by value involves using the copy constructor, so you enter the infinte loop. So your solution is to use pass by const reference.

0
source

Source: https://habr.com/ru/post/1307920/


All Articles