Can one of you explain why the following piece of code does not compile?
#include <iostream>
using namespace std;
class Foo
{
public:
Foo() { cout << "Foo::Foo()" << endl << endl; }
Foo& operator=(const Foo&) { cout << "Foo::operator=(const Foo&)" << endl << endl; }
private:
Foo(const Foo& b) { *this = b; cout << "Foo::Foo(const Foo&)" << endl << endl; }
};
int main()
{
Foo foo;
foo = Foo();
}
The error I receive:
$ g++ -o copy_ctor_assign copy_ctor_assign.cc && ./copy_ctor_assign
copy_ctor_assign.cc: In function 'int main()':
copy_ctor_assign.cc:10: error: 'Foo::Foo(const Foo&)' is private
copy_ctor_assign.cc:17: error: within this context
Note: when I remove the private: keyword the code compiles but the copy ctor is never called. So why does it err when it's private?
Not sure if it's important but I'm using:
$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
Copyright (C) 2006 Free Software Foundation, Inc.
You are initializing a reference from temporary.
The standard states:
The temporary should be initialized (8.5.3 par 5)"using the rules for a non-reference copy initialization (8.5)".
The copy construction is removed for the temporary (permitted by the standard. 12.8 par 5).
However, the standard clearly states (12.2 par 1):
"Even when the creation of the temporary object is avoided (12.8), all the semantic restrictions must be respected as if the temporary object was created. [Example: even if the copy constructor is not called, all the semantic restrictions, such as accessibility (clause 11), shall be satisfied. ]"
(also, when looking for the right quote, found this duplicate :)
Edit: adding relevant location from the standard
That code compiles with gcc 4.3.3 and 4.4.1. Maybe that's just a bug in gcc 4.1?
Assuming that the code you've posted is the only code in the project, and there's no covert passing of Foos by value going on anywhere, all I can figure is that gcc is optimizing
Foo foo;
foo = Foo();
to
Foo foo = Foo();
...which is unsound, as the first form is a default-construct and an assignment, while the second is equivalent to
Foo foo(Foo());
...which is clearly a copy construction. If I'm right, the copy constructor is not being run because GCC can optimize away the redundant temporary; this is permitted by the C++ spec.
In general, it is not a good idea to have assignment operators and copy constructors at different protection levels; as you've seen, the results can be unintuitive.
Copy Ctor is called when:
So you are certainly doing one or both of these case somewhere in your code. You should set Copy Ctor as public or avoid the 2 previous cases.
Copy constructor would be called if you write
Foo foo; // normal constructor
Foo foo1(foo); //copy constructor
In your case, first the default constructor is called and then the operator= method.
#include <iostream>
using namespace std;
class Foo
{
public:
Foo() { cout << "Foo::Foo()" << endl << endl; }
Foo& operator=(const Foo&) { cout << "Foo::operator=(const Foo&)" << endl << endl; }
Foo(const Foo& b) { *this = b; cout << "Foo::Foo(const Foo&)" << endl << endl; }
};
int main()
{
Foo f1;// default constructor called
Foo f2 = f1; //copy constructor called
}
Check this, in Foo f2=f1;
( f2
is created using copy constructor)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.