访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector

Accessing class member of std:vector of std:vector in a class with another std:vector

本文关键字:vector std 一个 另一个 成员 访问      更新时间:2023-10-16

我对如何在一个类中访问一个std::vector与另一个std::vector感到困惑。之前的讨论(为什么可以从函数返回"向量"?(处理了类似的问题,但似乎我一定误解了什么。

这是我的代码草图:

class Employee
m_id;
public:
set_id(int id);
id();
In Employee.cpp
void Employee::set_id(const int id)
{
m_id = id;          // m_id is 5
}
int Employee::id() const
{
return m_id;        // m_id is rubbish
}
class Company
public:
std::vector<Employee> m_employees;
In Company.cpp
void Company::addEmployee(const addEmployee employee) // A vant to pass a copy of employee
{
m_employees.push_back(employee);
}
std::vector<Employee> Company::employees()
{
return m_employees;
}
in myClass.h
std::vector<Company> m_companies;
in myClass.cpp  
int empl_id = 5;   // test value
m_companyIndex = 0;   // for test
m_emplIndex = 0;   // 
Company company; 
Employee employee;
m_companies.push_back(company);
m_companies.at(m_companyIndex).addEmployee(employee);
m_companies.at(m_companyIndex).employees().at(m_emplIndex).set_id(empl_id);
int idRet = m_companies.at(m_companyIndex).employees().at(m_emplIndex).id(); 
idRet contans an apparently random number, instead of 5. Using a debugger shos that 

如果我在 myClass 中实例化员工,我可以设置并回读m_id; 同上公司,所以问题似乎在类公司中实现了 std::vector m_employees; 。会不会和"回报值优化"有关?顺便说一下,我正在使用 gcc 7.5.4。

正如@dxiv所指出的,您的 Company::employees 函数构造并返回m_employees列表的副本。因此您的代码

m_companies.at(m_companyIndex).employees().at(m_emplIndex).set_id(empl_id);

翻译为:

Get the element of m_companies at the index m_companyIndex,
then construct a copy of its m_employees list,
then get the element of that copy at index m_emplIndex,
then set the id of that element to empl_id,
and then destroy the copy.

当然,这根本不会改变m_employees列表的内容。

您可以通过使 Company::employee 返回对员工列表的非常量引用而不是副本来使代码或多或少地正常工作。但是,这样的函数不能在"const"公司对象上调用,因此您可能还需要返回 const 引用的"const"版本。

但是,即使通过非 const 引用公开类的私有实现详细信息(如 m_employees(也是危险的,因为如果外部代码使用此引用来修改 m_employees 向量,则不会通知 Employees 类,并且它拥有的任何其他内部数据(可能依赖于 m_employees 向量的内容(都无法同时更新。

因此,外部代码通常最好要求包含类(员工(进行更改,而不是要求包含类返回外部代码可用于进行更改的非 const 引用。这样,Employee 类可以进行更改,还可以更新它可能依赖于m_employees内容的任何其他内部数据。

例如,您可以添加一个 Employees::at 函数,该函数返回对元素的引用,以便可以将上面的代码行重写为:

m_companies.at(m_companyIndex).at(m_emplIndex).set_id(empl_id);

甚至更好:

m_companies.at(m_companyIndex).set_id(m_emplIndex, empl_id);

甚至更好,如果m_companies包含在名为"公司"的公司对象中:

companies.set_id(m_companyIndex, m_emplIndex, empl_id);

使用这些函数,您可以更改 Employees::m_employees 以使用完全不同的数据结构(例如,排序列表、链表或集合(,而不会影响您的界面。这减少了外部代码与类内部代码之间的耦合,并且如果需要,将来可以更轻松地进行更改。

一般来说,在设计此类接口时考虑得墨忒耳定律是明智的,特别是对于用于改变对象内容的接口: 许多对象对外部类在他们不知情的情况下更改其内部内容的反应不佳,因此最好要求包含对象尽可能更改其子对象, 而不是允许从类外部访问对它们的非常量引用。

相关文章: