簡體   English   中英

朋友類訪問私有構造函數

[英]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 Bclass A Class BfriendB可以訪問私有構造函數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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM