[英]access to private constructor by friend class
问题:源代码(见下文)编译为MSVC,但不编译g ++。
#include <iostream>
using namespace std;
class B;
class A
{
friend class B;
private:
int i;
A(int n) : i(n) { }
public :
A(A& a) { if (&a != this) *this = a; }
int display() { return i;}
};
class B
{
public :
B() { }
A func( int j) { return A(j); }
};
int main(int argc, char **argv)
{
B b;
A a(b.func((10)));
cout << " a.i = " << a.display() << endl;
return 0;
}
输出:
GNU g++ compilation message:
g++ -c main.cpp
main.cpp: In member function 'A B::func(int)':
main.cpp:25:38: error: no matching function for call to 'A::A(A)'
A func( int j) { return A(j); }
^
main.cpp:25:38: note: candidates are:
main.cpp:17:9: note: A::A(A&)
A(A& a) { if (&a != this) \*this = a; }
^
main.cpp:17:9: note: no known conversion for argument 1 from 'A' to 'A&'
main.cpp:14:9: note: A::A(int)
A(int n) : i(n) { }
^
main.cpp:14:9: note: no known conversion for argument 1 from 'A' to 'int'
main.cpp: In function 'int main(int, char\**)':
...
为什么? Class B
是class A
Class B
的friend
, B
可以访问私有构造函数A(int i)
。
您的复制构造函数必须采用const
引用,以便它可以绑定到临时A
:
A(const A& a) { .... }
C ++标准不允许将非const引用绑定到临时引用。 g ++对此严格,而MSVC有一个“扩展”,打破了规则。
除此之外,你的拷贝构造函数的实现看起来很奇怪。 你不应该在那里使用赋值运算符。 对于像A
这样的类,您应该使用隐式生成的复制构造函数,换句话说,删除您自己的:
class A
{
friend class B;
private:
int i;
A(int n) : i(n) { }
public :
int display() const { return i;}
};
这是MS VC ++的一个错误。 它不应该编译代码。 问题是g ++的错误消息不够容易。
事实上,编译器试图避免使用复制构造函数,并使用构造函数A(int n);直接在'a'中构建对象。 但是可以使用适当的复制构造函数。 由于应复制临时对象(如果不使用ilision),则复制构造函数应具有对象的const引用。 那不是A(A&a); 您的复制构造函数应声明为A(const A&a); 如果你要进行更改,那么g ++将编译代码。
为您的示例定义复制构造函数的最简单方法是编写
A( const A & ) = default;
但是我不确定您的MS VC ++编译器是否支持此功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.