Copy Constructor and const

C

CPP beginner

Hi , could you explain me the mechanism of copy constructor:

#include <iostream>
#include <algorithm>
class FOO
{
public:
int size;
int* data;

explicit FOO(int size):size(size), data(new int[size]) {}

~FOO(){delete[] data;}

FOO(FOO & copy): size(copy.size), data(new int[copy.size])
{std::copy(copy.data, copy.data + copy.size, data);}

};


FOO f(FOO A)
{return A;}

int main()
{
FOO first(2);
FOO copy = f(first);
}

This code return:
test.cpp: In function ‘int main()’:
test.cpp:25: error: no matching function for call to ‘FOO::FOO(FOO)’
test.cpp:13: note: candidates are: FOO::FOO(FOO&)

But When i replace FOO(FOO & copy) by FOO(const FOO & copy), it works.
f(first) returns a FOO object, it is temporay so is it non const ?

I would like to understand the mecanism.
Thank you very much.
 
V

Victor Bazarov

CPP said:
Hi , could you explain me the mechanism of copy constructor:

#include <iostream>
#include <algorithm>
class FOO
{
public:
int size;
int* data;

explicit FOO(int size):size(size), data(new int[size]) {}

~FOO(){delete[] data;}

FOO(FOO & copy): size(copy.size), data(new int[copy.size])
{std::copy(copy.data, copy.data + copy.size, data);}

};


FOO f(FOO A)
{return A;}

int main()
{
FOO first(2);
FOO copy = f(first);
}

This code return:
test.cpp: In function ‘int main()’:
test.cpp:25: error: no matching function for call to ‘FOO::FOO(FOO)’
test.cpp:13: note: candidates are: FOO::FOO(FOO&)

But When i replace FOO(FOO & copy) by FOO(const FOO & copy), it works.

The expression 'f(first)' yields a temporary, which is then used to
construct 'copy'. A temporary cannot be bound to a reference to
non-const (that's the requirement), so the copy-construction fails.
f(first) returns a FOO object, it is temporay so is it non const ?

It is non-const, but 'FOO&' cannot be initialised with it. 'FOO const&'
OTOH can. A temporary is what's known as "modifiable rvalue". In the
next edition of the standard references to rvalues are going to be
introduced, for which you should be able to (and should in your case) write:

FOO(FOO&& rtemp) : size(rtemp.size), data(rtemp.data) {
rtemp.data = 0;
}

which is called a "move constructor" (not a copy).
I would like to understand the mecanism.

What does your favourite C++ book say about copy constructors and
reference initialisation?

Anyway, look up "reference binding" or "reference initialisation" in the
archives. The main point is that a reference to non-const object cannot
be initialised with a temporary.

V
 
C

CPP beginner

Victor said:
CPP said:
Hi , could you explain me the mechanism of copy constructor:

#include <iostream>
#include <algorithm>
class FOO
{
public:
int size;
int* data;
explicit FOO(int size):size(size), data(new int[size]) {}
~FOO(){delete[] data;}

FOO(FOO & copy): size(copy.size), data(new int[copy.size])
{std::copy(copy.data, copy.data + copy.size, data);}

};


FOO f(FOO A)
{return A;}

int main()
{
FOO first(2);
FOO copy = f(first);
}

This code return:
test.cpp: In function ‘int main()’:
test.cpp:25: error: no matching function for call to ‘FOO::FOO(FOO)’
test.cpp:13: note: candidates are: FOO::FOO(FOO&)

But When i replace FOO(FOO & copy) by FOO(const FOO & copy), it works.

The expression 'f(first)' yields a temporary, which is then used to
construct 'copy'. A temporary cannot be bound to a reference to
non-const (that's the requirement), so the copy-construction fails.
f(first) returns a FOO object, it is temporay so is it non const ?

It is non-const, but 'FOO&' cannot be initialised with it. 'FOO const&'
OTOH can. A temporary is what's known as "modifiable rvalue". In the
next edition of the standard references to rvalues are going to be
introduced, for which you should be able to (and should in your case)
write:

FOO(FOO&& rtemp) : size(rtemp.size), data(rtemp.data) {
rtemp.data = 0;
}

which is called a "move constructor" (not a copy).
I would like to understand the mecanism.

What does your favourite C++ book say about copy constructors and
reference initialisation?

Anyway, look up "reference binding" or "reference initialisation" in the
archives. The main point is that a reference to non-const object cannot
be initialised with a temporary.

V

Thank you very much
 
P

prasoonthegreat

In the OP's question the object is passed by value to the function
f...so the copy constructor is invoked at that time too......

Does copy construction fail at time too.....or it fails only at the
time of returning the temporary object?????/
 
P

prasoonthegreat

In the OP's question the object is passed by value to the function
f...so the copy constructor is invoked at that time (to create the
temporary) too......

So the copy construction should fail at that time too since
temporaries serve as targets for constant references only (here the
reference is non const ).....
but copy construction fails at the time of returning the temporary
only.....

Please explain why?????
 
V

Victor Bazarov

In the OP's question the object is passed by value to the function
f...so the copy constructor is invoked at that time (to create the
temporary) too......

It doesn't have to, if compiler optimises. It should be able to, yes.
So the copy construction should fail at that time too since
temporaries serve as targets for constant references only (here the
reference is non const ).....
Huh?

but copy construction fails at the time of returning the temporary
only.....

Please explain why?????

Please post the exact code you need the answer for, with your comments.

V
 
P

prasoonthegreat

What do u mean by Huh? Did I say something wrong correct me then....

I asked the question for the same code that was posted at the
beginning in this thread......
 
S

SG

In the OP's question the object is passed by value to the function
f...so the copy constructor is invoked at that time (to create the
temporary) too......

Since the example doesn't compile, there's nothing that can be invoked
at runtime. But yes, the function call is well-formed because 'first'
is a non-const lvalue and 'return' is followed by a an lvalue
expression 'A'. The error is with the copy initialization only
because the right hand side is an rvalue -- as Victor pointed out
already.
So the copy construction should fail at that time too since
temporaries serve as targets for constant references only (here the
reference is non const ).....

Huh?!

(translated: "What are you talking about?")


Cheers!
SG
 
V

Victor Bazarov

What do u mean by Huh? Did I say something wrong correct me then....

I asked the question for the same code that was posted at the
beginning in this thread......

You made a statement: "temporaries serve as targets for constant
references only". I don't understand that statement, hence the 'huh'.

V
 
P

prasoonthegreat

I meant "Temporary objects can only serve as targets of(for written by
mistake) a const reference, not a non-const reference".....

Any problem in this??????
 
V

Victor Bazarov

I meant "Temporary objects can only serve as targets of(for written by
mistake) a const reference, not a non-const reference".....

Any problem in this??????

Not sure.

Did you mean to say "only references to const can be bound to temporary
objects"? As in "references to non-const cannot be bound to a
temporary"? Yes. Isn't that what I said?

I think I'm beginning to understand what you're trying to point out.
My reply said that something in line with "the call to 'f' yields a
temporary", whereas what you say that even before the call to 'f'
returns, a copy has to be made to initialise the argument to be passed
to 'f'. Right?

Well, I am not sure how this thing works since 'f' is very simple and
its body exists in the scope. For all I know the statement

FOO copy = f(first);

can be replaced by the compiler with this one:

FOO copy(first);

since 'f' is just returning its argument. The Standard only requires
accessibility of the copy constructor, IIRC. *If* the call to the copy
constructor is to be made, then the compiler will try to match the
argument passed with the argument type declared.

V
 
P

prasoonthegreat

Not sure.

Did you mean to say "only references to const can be bound to temporary
objects"?  As in "references to non-const cannot be bound to a
temporary"?  Yes.  Isn't that what I said?

Ya i agree.......

I think I'm beginning to understand what you're trying to point out.
My reply said that something in line with "the call to 'f' yields a
temporary", whereas what you say that even before the call to 'f'
returns, a copy has to be made to initialise the argument to be passed
to 'f'.  Right?

Exactly that is what i am trying to say
What is your opinion on that?????
That should also be a reason for compile time error.....isn't it??
 
V

Victor Bazarov

Ya i agree.......



Exactly that is what i am trying to say
What is your opinion on that?????
That should also be a reason for compile time error.....isn't it??

Uh... Didn't I provide the answer right there, in the part you just
chose to remove in your reply?... Please go back and read my attempt to
explain the situation and if you'd like we can discuss it, but I would
prefer not to repeat myself here.

V
 
J

James Kanze

In the OP's question the object is passed by value to the
function f...so the copy constructor is invoked at that time
(to create the temporary) too......

Yes, at least conceptually.
So the copy construction should fail at that time too since
temporaries serve as targets for constant references only
(here the reference is non const ).....

Not in the code he posted. He passed an lvalue to a value
argument.
but copy construction fails at the time of returning the
temporary only.....

Because in his code, that was the only place a temporary was
involved. Because his copy constructor took a non-const
reference, it could not copy temporaries.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top