简体   繁体   English

朋友类访问私有构造函数

[英]access to private constructor by friend class

Problem: source code (see. below) is compiled MSVC , but does not compile g++. 问题:源代码(见下文)编译为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;
}

Output: 输出:

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\**)':
    ...

Why? 为什么? Class B is a friend for class A then B has access to private constructor A(int i) . Class Bclass A Class BfriendB可以访问私有构造函数A(int i)

Your copy constructor must take a const reference so it can bind to a temporary A : 您的复制构造函数必须采用const引用,以便它可以绑定到临时A

 A(const A& a) { .... }

The C++ standard does not allow binding a non-const reference to a temporary. C ++标准不允许将非const引用绑定到临时引用。 g++ is strict about this, while MSVC has an "extension" that breaks the rule. g ++对此严格,而MSVC有一个“扩展”,打破了规则。

Besides that, your implementation of the copy constructor looks strange. 除此之外,你的拷贝构造函数的实现看起来很奇怪。 You should not be using the assignment operator there. 你不应该在那里使用赋值运算符。 For a class like A , you should use the implicitly generated copy constructor, in other words, remove your own: 对于像A这样的类,您应该使用隐式生成的复制构造函数,换句话说,删除您自己的:

class A
{
  friend class B;
private:
    int i;    
    A(int n) : i(n) { }

public :
    int display() const { return i;}
};

It is a bug of MS VC++. 这是MS VC ++的一个错误。 It shall not compile the code. 它不应该编译代码。 The problem is that the error message of g++ is not cllear enough. 问题是g ++的错误消息不够容易。

In fact the compiler tries to elide using of a copy constructor and to build the object directly in 'a' using constructor A(int n);. 事实上,编译器试图避免使用复制构造函数,并使用构造函数A(int n);直接在'a'中构建对象。 But that it will be possible an appropriate copy constructor shall be available. 但是可以使用适当的复制构造函数。 As a temporary object should be copied (if the ilision would not be used) then the copy constructor shall have const reference to object. 由于应复制临时对象(如果不使用ilision),则复制构造函数应具有对象的const引用。 That is instead of A(A& a); 那不是A(A&a); your copy constructor shall be declared as A( const A& a); 您的复制构造函数应声明为A(const A&a); If you will make the changes then g++ will compile the code. 如果你要进行更改,那么g ++将编译代码。

The most simple way to define copy constructor for your example is to write 为您的示例定义复制构造函数的最简单方法是编写

A( const A & ) = default;

However I am not sure whether your MS VC++ compiler supports this feature. 但是我不确定您的MS VC ++编译器是否支持此功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM