【问题标题】:Instantiate a list inside a constructor in C++在 C++ 的构造函数中实例化一个列表
【发布时间】:2012-03-11 23:25:25
【问题描述】:

我正在尝试在 C++ 中的类中构建一个列表,但我不明白我做错了什么

class Car(){  
public:  
    Car();  
    ~Car();  
    list <Objects> myList;  //a list of some objects from one of my classes  
    list <Objects>::iterator it;  
    void addObject(Object obj);  
    void removeObject(Object obj);  
};  

Car::Car(){  
    //what do I need to add to initialize the list
    it = myList.begin();
};  

void addObject(Object obj){  
    //myList.insert(it, obj);  
    myList.push_back(obj);
}  

void removeObject(Object obj){  
    myList.remove(obj);  
} 

我没有收到任何构建错误,但是调试器对我大喊“表达式:列表插入迭代器超出范围”。我相信我没有在构造函数中初始化列表,这就是原因。我该怎么做? 谢谢

现在所有内容都已通过插入进行排序,但是我在从同一个列表中删除时遇到了问题。
我认为这与这些“可爱”的指针有关。为了一劳永逸地得到这个,我主要创建了一个 Car 类型的对象。然后我创建了一些 Object 类型的对象。然后我使用上面的代码将它们添加到我的 Car 对象中。为什么我不能删除它们?最重要的是:我使用这段代码创建了多少同一个对象的实例:

int main(){  
    Car myCar = Car();  
    Object one = Object("first object");  
    Object two = Object("second object");  
    Car.addObject(one);  
    Car.addObject(two);  
    Car.removeObject(one);  //doesn't work???
}  

有人可以向我解释我做错了什么吗?我按值传递对象有什么关系吗?执行上述操作的正确方法是什么?
谢谢。

【问题讨论】:

  • 就目前而言,代码看起来不错,但您应该确保您了解容器的迭代器失效行为。该列表将被正确初始化(到一个空列表)。
  • @Kerrek :这将默认初始化一个std::list&lt;&gt;::iterator,这是不行的。
  • @ildjarn:有什么问题?迭代器可以默认初始化。稍后,it 在构造函数主体中获得分配给它的有效值。不优雅,但实用。
  • @Kerrek :显然我很困惑。我在想容器的哨兵迭代器是不合法的,但事实上,只要你在使用它们之前为它们分配一个有效值,它们就是合法的,这是在这里完成的。
  • 我使用迭代器来显示存储在列表中的所有对象,如果/当我想将新对象添加到特定位置时,我想保持相同的方法。为什么说它不优雅?

标签: c++ list constructor


【解决方案1】:

您的列表将在您的构造函数中自动初始化,您不需要将迭代器作为类成员。要将您的对象添加到列表中,您只需调用 push_back:

void addObject(Object obj){  
myList.push_back(obj);  
}  

http://www.cplusplus.com/reference/stl/list/push_back/

要在特定位置插入,请参阅:http://www.cplusplus.com/reference/stl/list/insert/

如果你要任意决定在哪里插入你的新对象,那么你需要每次使用 find() 来确定哪里,如果你总是在开头或结尾插入,那么调用很容易

// insert in arbitrary location
myList::iterator it = myList.find(val);
myList.insert(it, obj);
// OR insert at beginning
myList.push_front(obj); // to insert at end see above

【讨论】:

  • 也许 OP 也有一些理由来跟踪迭代器。没有进一步的信息是不可能的。也许设置不寻常,但并非不可能。
  • 如果您想设置最小或默认大小或该大小的默认值,我只会初始化列表,每次您向列表中添加新元素时,您的迭代器都会失效,所以没有意义跟踪它,除非您希望它始终指向列表的末尾,即它 = myList.end();。无论如何,请说明您想要实现的目标。
  • 当页面想要更新这个页面时,我正要给出类似的答案。对于 TC,我怀疑调试器认为 begin 迭代器无效,因为列表为空。但正如我们所说,你不需要它。此外,一旦删除了迭代器成员,您的类就根本不需要指定构造函数(或析构函数);默认的生命周期管理行为应该做正确的事情(除非真正的代码有构建和/或分解代码,这里跳过以使示例更短)。
  • push_back(obj) 的作用就像一个魅力,但是,稍后如果我想将一个对象添加到一个特定的地方,我相信这种方法不是推荐的方法。谢谢。
  • 在 myList.begin() 或 myList.end() 处使用 insert 和指向您希望它指向的位置的迭代器,或者执行像 iterator it = myList.find(obj); 这样的查找调用然后调用 myList.insert(it);这里重要的是,您希望迭代器在您从列表中插入或删除元素后仍然有效,因为如果您考虑一下,您可能已经更改了某些元素的顺序。
【解决方案2】:

你的列表已经初始化好了。

调试器试图提供帮助并显示it 迭代器指向的元素。由于您没有向列表中添加任何元素,因此列表为空,并且myList.begin() 未指向有效元素。

将元素添加到列表后,错误消息就会消失。但是,我不确定您的 it 迭代器是否会自动生效,或者您是否需要再次调用 myList.begin()

您尚未发布您的 Object 类定义,但删除可能不起作用,因为您的 Object 类未正确实现 operator==。与指针无关(除非Object 在内部使用指针)或按值传递。

将您的方法声明为 void addObject(Object obj) 而不是 void addObject(const Object&amp; obj) 确实意味着对于每次调用,您都将创建一个额外的 Object 实例。

【讨论】:

  • “类没有正确实现operator==”是什么意思?将 Object 类完全视为没有任何方法的 Car 类。我不确定我是否理解在该课程中在哪里使用== 以及用于什么。谢谢
【解决方案3】:

我在这里看到的唯一一件事是您可能正在使用 list.end() 的地方,而您没有在这里显示。请记住, list.end() 实际上指向列表的末尾,而不是列表的实际最后一个成员。要追加到列表中,最好使用 'push_back'。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多