在没有指针的情况下修改容器中的对象:向量与集合

Posted

技术标签:

【中文标题】在没有指针的情况下修改容器中的对象:向量与集合【英文标题】:Modify object in container without pointer: vector vs set 【发布时间】:2017-04-02 22:15:36 【问题描述】:

我可以访问以下列方式生产对象的工厂:

A a = factory.build();

我想将A 类型的对象存储在一个容器中,访问它们,修改它们的内部状态,然后我通过容器访问对象,我想像以前一样访问对象(修改后的状态)。 我的第一个想法是将指向A 的指针存储在容器中。但是,如上所述,工厂并没有给我一个指向对象的指针,而是对象本身。

A类:

class A

  private:
    int id;

  public:
    A(int id)
    
      this->id = id;
    

    int getId() const
    
      return id;
    

    void setId(int id)
    
      this->id = id;
    
;

我发现以下使用 vector 有效:

A obj1(1);

std::vector<A> vec;
vec.push_back(obj1);

A & obj = vec[0];
obj.setId(4);

for(std::vector<A>::iterator itr = vec.begin();itr!=vec.end();itr++)

    std::cout << (*itr).getId() << endl;

这会打印修改后的 id:4。

使用std::set 可以实现类似的功能吗?我尝试了以下方法:

struct AComp

  bool operator()(const A lhs, const A rhs) const
  
    return (lhs.getId() < rhs.getId());
  
;

A obj2(1);

std::set<A, AComp> mySet;
mySet.insert(obj2);

int id = 1;
auto result = std::find_if(mySet.begin(), mySet.end(), [id](A a) return a.getId() == id;);

A tmp = *result;
tmp.setId(4);
std::cout << tmp.getId() << endl;

for(std::set<A>::iterator itr = mySet.begin(); itr!=mySet.end();itr++)

    std::cout << (*itr).getId() << endl;

当然,这不会改变集合中对象的状态。但是这里我不能说

A & tmp = *result;

这给了我:

binding ‘const hallo2::A’ to reference of type ‘hallo2::A&’ discards qualifiers

我将如何使用std::set 实现这一目标?

【问题讨论】:

如果你问是否可以修改集合中包含的对象,答案是否定的。 【参考方案1】:

错误告诉您*resultconst A&amp;,这意味着您不能通过此引用修改对象。

那是因为您不能修改集合中的对象。如果你真的想要,那么你必须移除并重新插入对象。

【讨论】:

谢谢。在vector 中被允许但在set 中被禁止的原因是什么? 改变向量中事物的值不能使向量本身无效。更改集合中事物的值(几乎总是以平衡二叉树的形式实现)会使树无效,从而使集合无效。 啊,有道理。谢谢!【参考方案2】:

您没有提供工厂类或构建方法,所以我不得不假设您指的是标准模式。

但是,如果您只需要一个指向对象的指针,那么应该这样做:

Aptr *A;

Aptr aptr = &(factory.build());

【讨论】:

但是来自factory.build()的对象不是在堆上创建的,所以当离开factory.build()内的范围时,调用这个对象时,不是吗? 一个好问题。我不知道。这将取决于它是如何实现的,并且没有提供该代码。

以上是关于在没有指针的情况下修改容器中的对象:向量与集合的主要内容,如果未能解决你的问题,请参考以下文章

JAVA 中的集合框架

Java的集合类

Java 集合类

Java中各种集合总结

JAVA集合类汇总

保存计时器集合的最佳方法(对象与指针)