[英]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.