我试图理解类的成员函数在创建私有变量的本地副本时的行为。 (通过引用访问时不是)
所以我有了这个代码,我的理解是这样的:
>
在成员函数get_name0()中,向量“name”是私有数据成员“name”的本地副本。
在get_name0()函数中添加元素“f0”应该使对象np0具有{ab,f0},它确实如此。 这里没问题。
在main函数中添加元素“m0”应该使(?) 对象np0具有{ab,f0,m0},但它具有{ab,f0,f0}。 我不明白为什么会出现这种情况,也许我在什么地方错了?
提前感谢任何为我澄清这一点的人!
class Name_pairs
{
public:
vector<string> get_name0() // this is a member function that returns a copy; name is a local copy
{
name.push_back("f0"); // the copy can be changed by the member function
return name;
}
private:
vector<string> name = {"ab"};
};
int main()
{
Name_pairs np0;
np0.get_name0().push_back("m0"); // this should change the local copy not the "name" object but it doesn't
cout << "\nnp0 object: ";
for (string s : np0.get_name0()) // this should print the local copy from the inside of get_name0() function
cout << s << " ";
}
get_name()
返回成员的副本。 两个不同的调用返回成员的两个不同副本。
这将产生预期的产出:
int main()
{
Name_pairs np0;
auto name = np0.get_name0();
name.push_back("m0");
cout << "\nnp0 object: ";
for (string s : name)
cout << s << " ";
}
在您的代码中没有“本地副本”。 返回的向量是在语句末尾不再存在的临时向量。
不是。在成员函数name
中是名为name
的成员。 从方法返回的是一个副本。
这里没问题,但是您是在添加到成员中,而不是添加到某个“本地副本”中。 首先添加,然后复制(并从方法返回副本)。
添加“M0”
的对象在此行之后:
np0.get_name0().push_back("m0");
它的生命结束了。 你得想方设法再见到它。 在再次向成员添加“F0”
之后,对get_name0()
的下一次调用将为您提供该成员的新副本。
每次调用get_name0
都会将值f0
添加到name
向量中。 由于您对该函数进行了2次调用,因此将插入2个f0
副本。 注意,range-for循环中的用法也是对此函数的调用。
但是,get_name0
返回的向量是name
向量的副本,因此向该副本添加元素不会更改成员变量。 如果要实际更改成员,则需要通过引用返回向量,如下所示:
vector<string>& get_name0() {
您的函数get_name0
按值返回,而不是按引用返回,因此在您的示例中
np0.get_name0().push_back("m0");
表现为
{
vector<string> temporary = np0.get_name0();
temporary.push_back("m0");
} // here temporary is destroyed
您的push_back(“m0”);
只修改临时的,而不是存储在NP0
中的向量
。 如果要修改vector
indnp0
,则get_name0
应通过引用返回。
vector<string>& get_name0();
注意,使用get_name0
,您将授予类的客户端对数据成员的完全访问权限。 如果只希望客户端读取数据,则使返回的vector
const
const vector<string>& get_name0();
或者完全删除该函数,只提供所需的成员修改函数(例如add_name
)。