1

这应该是一个简单的问题,但对于我来说,我无法在网上找到解决方案。

简而言之,创建一个对象并将其添加到指针列表中对我不起作用 - 一旦我尝试以与创建它的位置不同的方法访问列表中的项目,它就会产生访问冲突。

所以两个问题:

1:最好的方法是什么?

2:随后,如果不使用指针列表,从列表中删除的最佳方法是什么?

int main( int argc, const char* argv[] )
{
    std::list<testClass*> list;
    addClass(list);
    std::cout << list.front()->a; //item added to list now longer accessible
}

void addClass(std::list<testClass*> list)
{
    testClass* c = new testClass();
    c->a = 1; c->b = 2;
    list.push_back(c); //item still accessible here
}



class testClass
{
public:
    int a;
    int b;
};
4

2 回答 2

4

您需要list通过引用传递,您在此处传递值,因此它正在制作容器的副本并处理该副本:

void addClass(std::list<testClass*> list)

如果您像这样修改它,它应该可以按您的意愿工作:

void addClass(std::list<testClass*> &list)
于 2013-06-10T12:06:15.880 回答
0

第一个宏观错误是addClassshold采取a std::list<testClass*> &,以便它在main中包含的列表上操作,而不是在本地副本上。

在那之后,整个设计必须更好地聚焦:

  • 由于testClass不是多态的(其中没有虚拟的),动态分配它们有什么意义?让它们作为值直接包含在列表本身中可能会更容易,havig a std::list<testClass>.

  • 或者......如果您需要动态分配,您还必须考虑取消分配,否则您将泄漏内存:如果列表包含指针,它将破坏指针,而不是它们指向的内容。

所以现在,让我们跟随两条轨道:

将对象视为值

您需要一种testClass从给定值构造对象的方法。

class testClass
{
public:
    testClass(int a_, int b_) 
       :a(a_), b(b_)
    {}

    int a;
    int b;
};

现在你可以

void addClass(std::list<testClass>& list)
{
    list.emplace_back(1,2);
}

int main()
{
    std::list<testClass> list;
    addClass(list);
    std::cout << list.front().a; 
}

注意有些人是如何*消失的!

动态处理对象

好的,用新的创建,但你必须注意删除。

一种方法是从列表中删除指向:就在}in main...

for(auto p : list) delete p;

这将在列表中运行并为每个指针调用 delete,从而释放(并销毁)您使用 new 分配的对象。

注意: 这不会使列表为空:列表仍然包含指针,它们只是指向无效地址。指针将在退出时由列表释放main

另一种方法是不使用普通指针,而是使用智能指针,在内容被销毁时自行删除内容。

这需要一个std::list<std::unique_ptr<testClass> >作为容器,以便您可以

void addClass(std::list<std::unique_ptr<testClass> >& list)
{
    list.emplace_back(new testClass(1,2)); 
}

现在,当退出时,列表会被自己的元素(智能指针)破坏,而分配的对象main又会被破坏。deletenew

于 2013-06-10T12:44:13.963 回答