如何从类外修改向量
Posted
技术标签:
【中文标题】如何从类外修改向量【英文标题】:How can I modify a vector from outside the class 【发布时间】:2019-04-13 13:30:22 【问题描述】:我怎样才能访问课堂外的私有向量?我想修改这个对象的参数。
我尝试制作getter并通过引用返回向量,但是当我尝试更改主函数中vector中包含的对象的参数时,不会保存vector中的更改。
class Restaurant
std::vector <Waiter> waiters_vector_;
public:
inline std::vector<Waiter> &GetWaitersVector() return waiters_vector_;
void Restaurant::AddWaiter(Waiter tmp)
waiters_vector_.push_back(tmp);
Restaurant();
~Restaurant();
;
class Waiter
int current_group_id_=0;
public:
int GetCurrentGroupId()
return current_group_id_;
void SetCurrentGroupId(int tmp)
current_group_id_ = tmp;
Waiter();
~Waiter();
;
int main()
Restaurant restaurant1;
Waiter w1, w2, w3;
restaurant1.AddWaiter(w1);
restaurant1.AddWaiter(w2);
restaurant1.AddWaiter(w3);
for (Waiter element : restaurant1.GetWaitersVector())
element.SetCurrentGroupId(123);
for (Waiter element : restaurant1.GetWaitersVector())
std::cout << element.GetCurrentGroupId() << std::endl;
结果: 0 0 0
【问题讨论】:
关于软件设计的说明:将向量私有化的全部意义在于控制类的接口及其与其余代码的通信。通过 getter 暴露向量几乎完全没有意义,并且违反了“告诉,不问”的设计原则。该类不应提供直接访问,而应有选择地提供仅修改实际需要修改的方面的方法(并且这些应尽可能少,最好没有)。 编译错误:“void Restaurant::AddWaiter(Waiter tmp)”在声明内部给出“错误:成员‘AddWaiter’[-fpermissive]上的额外限定‘Restaurant::’”~Restaurant();
可能想成为~Restaurant() = default;
【参考方案1】:
你的两个for
循环都在复制
for (Waiter element : restaurant1.GetWaitersVector())
你想修改对实际对象的引用
for (Waiter& element : restaurant1.GetWaitersVector())
【讨论】:
第一个循环复制 EACH ELEMENT ITERATED OVER,其范围是循环本身(即在当前迭代结束时销毁)。只是想我会补充一点,以便清楚起见。您的回答简单明了!【参考方案2】:for (Waiter element : restaurant1.GetWaitersVector())
使用向量的副本进行操作。
如果要对引用进行操作,请使用
for (auto& element : restaurant1.GetWaitersVector())
// ^^^^^
改为。
但是除了上面提到的之外,暴露你的实习向量是一个糟糕的设计理念。你应该有一个吸气剂
inline const std::vector<Waiter> &GetWaitersVector() const return waiters_vector_;
从而强制访问它的客户端使用您的类的特定功能(如AddWaiter()
)来修改它。
【讨论】:
很确定auto element
不是参考,而是副本。你的意思是Waiter& element
?
@KonradRudolph 我不确定auto
是否应该自动推断出引用,请澄清一下。
@πάνταῥεῖ AFAIK auto
从不推断参考。
@πάντα ῥεῖ - 这是真的。
您说 “使用向量的副本进行操作” 但我认为您的意思是“使用元素的副本进行操作”不是吗?【参考方案3】:
我怎样才能访问课堂外的私有向量?我想修改这个对象的参数。
你没有。或者更确切地说,您需要决定:服务员的向量是私有的,还是不是?是否是使用此类的代码不应该知道的实现细节?如果不是,您真的希望能够在外部按原样操作它吗?或者您可能想使用PIMPL idiom 提供一个.waiters()
方法,该方法返回一个晦涩的类,方法包括add(...)
、`remove(...) 等?
这些是您需要做出的设计决策。
【讨论】:
以上是关于如何从类外修改向量的主要内容,如果未能解决你的问题,请参考以下文章