[英](Copy Constructor) How does the object passed as parameter to initialize another object have access to the private members?
Example code: 示例代码:
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;
}
How is object2 initialized by passing it object1? 如何通过传递object1来初始化object2? As far as I can see object1 can't access the member
x
directly, then how does it help in initializing object2? 据我所知,object1无法直接访问成员
x
,那么它如何帮助初始化object2?
Private applies to classes not objects . 私有适用于类而不是对象 。 Any object of class X has access to the private members of all other objects of class X.
类X的任何对象都可以访问类X的所有其他对象的私有成员。
Access control (public/private/protected) controls whether a piece of code can legally refer to a name of a class's member. 访问控制(公共/私有/受保护)控制一段代码是否可以合法地引用类成员的名称。 Individual objects don't play a role here;
个别物品在这里不起作用; the whole problem is just about code and names.
整个问题只是代码和名称。
Let's compare the constructor from your question, a friend function and a free function: 让我们比较一下你问题中的构造函数,一个友元函数和一个自由函数:
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;
}
Take the statement x = obj.x;
采用声明
x = obj.x;
. 。 A statement is a piece of code.
声明是一段代码。 Where is that piece of code?
这段代码在哪里? Inside the constructor of class
my
. 在
my
的类的构造函数里面。 So it's a part of the class and so it can access the name obj.x
. 所以它是类的一部分,因此它可以访问名称
obj.x
Next, the statement obj.x += 1;
接下来,语句
obj.x += 1;
. 。 Where is that piece of code?
这段代码在哪里? Inside the function
fr
, which is a friend of class my
. 在函数
fr
里面,这是my
的朋友。 It's a friend, so it can access the name obj.x
. 它是朋友,所以它可以访问名称
obj.x
Finally, the statement obj.x += 2;
最后,语句
obj.x += 2;
. 。 Where is that piece of code?
这段代码在哪里? Inside the function
nonfr
. 在函数
nonfr
里面。 nonfr
is an ordinary function unrelated to class my
, so it has no right to access the names of private (or protected) members of class my
, so it will fail to compile. nonfr
是一个与class my
无关的普通函数,因此它无权访问my
类的私有(或受保护)成员的名称,因此无法编译。
Side notes: 附注:
Normally, a copy constructor should take its parameter by reference to const, like this: 通常,复制构造函数应该通过引用const来获取其参数,如下所示:
my(const my &obj)
Copy constructors which take by non-const reference can modify the source object, and viable use cases for them are extremely rare. 使用非const引用的复制构造函数可以修改源对象,并且它们的可行用例非常罕见。 Not to mention that they prevent copying from temporaries, since those can't bind to non-const references.
更不用说它们会阻止从临时文件中复制,因为它们无法绑定到非const引用。
Also, it's generally preferable to use mem-initialiser-lists instead of assignment inside the constructor, because the latter first initialises the member and then assings to it. 此外,通常最好使用mem-initialiser-lists而不是在构造函数中赋值,因为后者首先初始化成员然后对其进行赋值。 So in total, the constructor should look like this:
总的来说,构造函数应该如下所示:
my(const my &obj) : x(obj.x)
{}
Not to mention the fact that unless you need special handling in the copy constructor (which you don't here), you shouldn't declare it at all and let the compiler generate it for you. 更不用说除非你需要在复制构造函数中进行特殊处理(你不在这里),否则你不应该声明它并让编译器为你生成它。 See Rule of Zero and Rule of Three for more information.
有关详细信息,请参阅零度规则和三个规则 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.