Lets "inline" the function call:
1 2 3 4 5 6 7 8 9 10 11
|
class T {
// code
};
int main() {
T bar;
{
T val( bar );
// code from foo
}
}
|
That similar to what the function call does.
The argument 'val' of foo is
copy constructed with the parameter (bar) that foo was called with.
Lets put it other, explicit, way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
class T {
// code
public:
T() = default;
T( const T& ) = delete;
};
void foo( T val ) {
// code
}
int main() {
T bar;
foo( bar ); // error
}
|
In function 'int main()':
14:12: error: use of deleted function 'T::T(const T&)'
5:3: note: declared here
8:6: error: initializing argument 1 of 'void foo(T)' |
What went wrong?
We told on line 5 that the class T does not need copy constructor.
We told compiler to not create any copy constructor for T.
The result: line 14, function call with
by value parameter is not possible, because T does not have copy constructor.
Conclusion: copy constructor is not "like" by value parameter.
To pass parameter by value
requires copy constructor.
To pass parameter by value
uses copy constructor.
You probably create more copies than you realize.
Do not ask "
how to use copy constructor".
The copy constructor is the
answer to "
What happens when I (attempt to) create a copy?"
Copy assignment is closely related to copy constructor. The difference is that data is copied to already existing object.
Move constructor and move assignment are more recent. Rather than copy, data moves and source object is modified.