访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector
Accessing class member of std:vector of std:vector in a class with another std:vector
我对如何在一个类中访问一个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 以使用完全不同的数据结构(例如,排序列表、链表或集合(,而不会影响您的界面。这减少了外部代码与类内部代码之间的耦合,并且如果需要,将来可以更轻松地进行更改。
一般来说,在设计此类接口时考虑得墨忒耳定律是明智的,特别是对于用于改变对象内容的接口: 许多对象对外部类在他们不知情的情况下更改其内部内容的反应不佳,因此最好要求包含对象尽可能更改其子对象, 而不是允许从类外部访问对它们的非常量引用。
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++从 std::vector<std::function<中删除 std::function>>
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 将 std::vector<std::unique_ptr<T>> 移动到 std::vector<std::shared_ptr<T>>
- 如何从 boost::container::vector<std::string>::iterator 访问索引和对象?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 为什么转置这个 std::vector<std::vector<std::string> > 这么慢?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 如何从 std::initializer_list<char const* 构建 std::vector<std::string>>
- 如何检查 std::vector<std::string> 的元素是否以某个子字符串开头?
- 在 std::vector<std::vector 中重新存储内部向量<TYPE>>
- 将 std::vector<std::string> 转换为 const char* const*
- 不能将结构push_back() 转换为 std::vector<std::shared_ptr<theStruct>> theVector
- SWIG:传递一个 std::vector< std::vector <double> >指向 python 的指针
- 将 std::vector<std::p air<const K, V>*> 转换为 std::vector<std::p air<const K, V>&g