在没有指针的情况下修改容器中的对象:向量与集合
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】:错误告诉您*result
是const A&
,这意味着您不能通过此引用修改对象。
那是因为您不能修改集合中的对象。如果你真的想要,那么你必须移除并重新插入对象。
【讨论】:
谢谢。在vector
中被允许但在set
中被禁止的原因是什么?
改变向量中事物的值不能使向量本身无效。更改集合中事物的值(几乎总是以平衡二叉树的形式实现)会使树无效,从而使集合无效。
啊,有道理。谢谢!【参考方案2】:
您没有提供工厂类或构建方法,所以我不得不假设您指的是标准模式。
但是,如果您只需要一个指向对象的指针,那么应该这样做:
Aptr *A;
Aptr aptr = &(factory.build());
【讨论】:
但是来自factory.build()
的对象不是在堆上创建的,所以当离开factory.build()
内的范围时,调用这个对象时,不是吗?
一个好问题。我不知道。这将取决于它是如何实现的,并且没有提供该代码。以上是关于在没有指针的情况下修改容器中的对象:向量与集合的主要内容,如果未能解决你的问题,请参考以下文章