通过友元类访问私有构造函数
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
friend
,然后B
可以访问私有构造函数A(int i)
。
复制构造函数必须采用const
引用,以便它可以绑定到临时A
:
A(const A& a) { .... }
C++ 标准不允许将非常量引用绑定到临时引用。 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 ++编译器是否支持此功能。
相关文章:
- 固有构造函数的字符和访问级别
- C++:为什么无法在派生类中访问受保护的构造函数?
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?
- c++ cuda:cudaMalloc在构造函数之外的托管访问
- 使用值初始化访问构造函数?
- 限制variadic模板类中的构造函数访问
- 构造函数无法访问继承类私有 int
- 从派生类访问模板基类的构造函数
- 如何在构造函数中访问类变量以分配它们,而无需在C++中使用此指针
- 访问在构造函数期间创建的值 - C++
- 从析构函数访问模板类构造函数的参数,可以吗?
- 仅当构造函数具有参数时,C++ 公共成员才能访问
- 正确的友元定义,以授予 std::map 对私有默认构造函数的访问权限
- 在派生类的构造函数初始化中无法访问受保护的函数
- 是否可以从 C++ 中的构造函数访问对象名称?
- 从构造函数访问值
- 聚合初始化不支持构造函数访问
- 无法从构造函数访问私有变量 - 不在范围(C )中
- c++工厂.子构造函数不能从父构造函数访问
- 如何通过类构造函数访问私有静态成员变量