如何从类外修改向量

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&amp; element @KonradRudolph 我不确定auto 是否应该自动推断出引用,请澄清一下。 @πάνταῥεῖ AFAIK auto 从不推断参考。 @πάντα ῥεῖ - 这是真的。 您说 “使用向量的副本进行操作” 但我认为您的意思是“使用元素的副本进行操作”不是吗?【参考方案3】:

我怎样才能访问课堂外的私有向量?我想修改这个对象的参数。

你没有。或者更确切地说,您需要决定:服务员的向量是私有的,还是不是?是否是使用此类的代码不应该知道的实现细节?如果不是,您真的希望能够在外部按原样操作它吗?或者您可能想使用PIMPL idiom 提供一个.waiters() 方法,该方法返回一个晦涩的类,方法包括add(...)、`remove(...) 等?

这些是您需要做出的设计决策。

【讨论】:

以上是关于如何从类外修改向量的主要内容,如果未能解决你的问题,请参考以下文章

如何将对象向量从类返回到 main.cpp

从类修改表单中的标签和对象 (VB.NET)

从类指针向量创建成员变量向量

如何修改 lambda 中的字符串向量

C++从类的向量指针访问类的成员

传递给函数的向量没有被修改