C++ 按友元类访问私有构造函数

C++ 按友元类访问私有构造函数,c++,C++,问题:源代码(见下文)是由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() { retur

问题:源代码(见下文)是由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;
}

为什么?
Class B
Class a
朋友
,然后
B
可以访问私有构造函数
a(inti)

您的副本构造函数必须具有
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++的一个bug。不应编译代码。问题是g++的错误消息不够清晰

事实上,编译器试图避免使用复制构造函数,并使用构造函数a(int n);,直接在“a”中构建对象;。但有可能提供适当的复制构造函数。由于应复制临时对象(如果不使用ilision),则复制构造函数应具有对对象的常量引用。而不是A(A&A);您的副本构造函数应声明为A(常量A&A);如果要进行更改,那么g++将编译代码

为示例定义复制构造函数最简单的方法是编写

A( const A & ) = default;

但是,我不确定您的MS VC++编译器是否支持此功能。

您的构造函数
A(A&A){if(&A!=this)*this=A;}
调用自身@lrineau不,它调用默认的复制赋值操作。然而,这个类很奇怪,没有正确地遵循复制赋值操作。@Angew是的,你是对的。谢谢你的精确性。
A( const A & ) = default;