#include <iostream>
class A {
public:
A(){ cerr << "A Constructor" << endl; }
~A(){ cerr << "A Destructor" << endl; }
A(const A &o){ cerr << "A Copy" << endl; }
A& operator=(const A &o){ cerr << "A Assignment" << endl; return *this; }
};
class B : public A {
public:
B() : A() { cerr << "B Constructor" << endl; }
~B(){ cerr << "B Destructor" << endl; }
private:
B(const B &o) : A() { cerr << "B Copy" << endl; }
B& operator=(const B &o){ cerr << "B Assignment" << endl; return *this; }
};
int main() {
A a;
const A &b = B();
return 0;
}
In GCC 4.2, I get this message:
In function 'int main()':
Line 16: error: 'B::B(const B&)' is private
compilation terminated due to -Wfatal-errors.
If I remove the “private” from B, I get the output I expect:
A Constructor
A Constructor
B Constructor
B Destructor
A Destructor
A Destructor
My question is: why does making a method which isn’t called private change whether this code compiles? Is this standard-mandated? Is there a workaround?
The important verbiage in the current standard (C++03) seems to be in §8.5.3, which explains how references are initialized (In these quotes,
T1is the type of the reference being initialized andT2is the type of the initializer expression).So, even if the implementation binds the reference directly to the temporary object, the copy constructor must be accessible.
Note that this is changed in C++0x, per the resolution of CWG defect 391. The new language reads (N3092 §8.5.3):
The first case applies and the reference is "bound directly" to the initializer expression.