示例代码:
class my
{
int x;
public:
my(int a)
{
x = a;
}
my(my &obj)
{
x = obj.x;
}
.
.
}
int main(void)
{
my object1(5);
my object2(object1);
return 0;
}
如何通过传递object1来初始化object2?据我所知,object1无法x
直接访问该成员,那么它对初始化object2有何帮助?
访问控制(公共/私有/受保护)控制一段代码是否可以合法地引用类成员的名称。单个对象在这里不起作用;整个问题仅与代码和名称有关。
让我们比较一下您的问题的构造函数,一个朋友函数和一个自由函数:
class my
{
int x;
friend void fr(my&);
public:
my(my &obj)
{
x = obj.x;
}
};
void fr(my &obj)
{
obj.x += 1;
}
void nonfr(my &obj)
{
obj.x += 2;
}
接受声明x = obj.x;
。语句是一段代码。那段代码在哪里?在类的构造函数内部my
。因此,它是类的一部分,因此可以访问名称obj.x
。
接下来,声明obj.x += 1;
。那段代码在哪里?在函数内部fr
,这是类的朋友my
。是朋友,因此可以访问名称obj.x
。
最后,声明obj.x += 2;
。那段代码在哪里?里面的功能nonfr
。nonfr
是与class无关的普通函数my
,因此它无权访问class的私有(或受保护)成员的名称my
,因此将无法编译。
旁注:
通常,复制构造函数应通过引用const来获取其参数,如下所示:
my(const my &obj)
通过非const引用获取的复制构造函数可以修改源对象,并且它们的可行用例非常少见。更不用说它们阻止了从临时对象的复制,因为那些临时对象无法绑定到非const引用。
同样,通常最好在构造函数内部使用mem-initialiser-list而不是赋值,因为后者首先初始化成员,然后再对其赋值。因此,总的来说,构造函数应如下所示:
my(const my &obj) : x(obj.x)
{}
更不用说一个事实,除非您需要在复制构造函数中进行特殊处理(您不在此处),否则根本不应该声明它,而让编译器为您生成它。有关更多信息,请参见零规则和三规则。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句