【发布时间】:2011-03-16 00:24:18
【问题描述】:
#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;
}
在 GCC 4.2 中,我收到以下消息:
In function 'int main()':
Line 16: error: 'B::B(const B&)' is private
compilation terminated due to -Wfatal-errors.
如果我从 B 中删除“私有”,我会得到我期望的输出:
A Constructor
A Constructor
B Constructor
B Destructor
A Destructor
A Destructor
我的问题是:为什么制作一个不称为私有的方法会改变这段代码是否编译?这是标准规定的吗?有解决办法吗?
【问题讨论】:
-
我不明白为什么这不应该编译。 FWIW,Comeau 同意我的观点。
-
@sbi:奇怪的是,Comeau 拒绝了禁用 C++0x 扩展的代码,但接受了启用了 C++0x 扩展的代码。
-
g++ 4.4.2,FWIW 没有错误。
-
gcc 4.5 接受带有和不带有 C++0x 扩展的代码。
-
@James McNellis:在 C++03 中,当从右值初始化 const 引用时,允许实现从右值构造一个临时并将引用绑定到该临时(允许这样做递归!)或直接绑定到右值。无论使用与否,复制构造函数都必须是可访问的。 C++0x 重新审视了这一点,如果右值是引用兼容的,则引用必须直接绑定到右值;不再允许使用临时对象,因此对拥有可用复制构造函数的限制也已取消。