创建一个类,其静态成员容器包含所述类的所有实例
Creating a class with a static member container holding all instances of said class?
我的目标是创建一个类,它将从它创建的每个实例添加到静态成员容器中,以便可以轻松访问所有实例。
在游戏中,对象是在Game.init()
函数中创建的,然后添加到容器中。然后,Game.update()
和Game.Draw()
函数遍历容器来访问和操作对象。
我希望构造函数和解构函数来处理这些任务,而不是手动向容器中添加或从容器中删除对象。
指针在对象(代码中的box)被复制或赋值时失效,这是一个问题。使用对象容器而不是指针到对象容器导致生成过多的副本,并且我无法使用引用来实现此功能。我正在寻找一些关于如何改进这段代码以避免这些问题的技巧(使用指针到对象的容器不是必需的,实际上我宁愿避免使用指针,但没有它们却无法使其工作):
#include <list>
#include <iostream>
class Box
{
private:
std::list <Box*>::iterator iter;
public:
static std::list <Box*> List;
Box() {
List.push_front(this);
iter = List.begin();
std::cout << "Constructing box." << std::endl;
}
~Box() {
std::cout << "Trashing box." << std::endl;
List.erase(iter);
}
void lookInside() {
std::cout << "It's empty." << std::endl;
};
};
std::list <Box*> Box::List;
int main()
{
Box Box_1;
Box Box_2;
Box Box_3;
Box_1 = Box_2; // causes problems!
for (auto iter : Box::List) {
iter->lookInside();
}
std::cout << "The list contains " << Box::List.size() << " boxes." << std::endl;
return 0;
}
你违反了三/五规则。
毫无疑问,您需要重载赋值和复制构造(至少)以使您的类按预期工作。默认的复制构造函数只会复制迭代器,因此最终得到的第二个对象包含原始迭代器的副本,并指向原始对象,因此当其中一个副本被销毁时,该项将从集合中删除。
显然,你想要的是向集合中添加一个新对象,并在复制构造完成时让该对象保存指向集合中新对象的迭代器。
同样,默认赋值操作符将迭代器从源对象复制到目标对象。你可能只是想让迭代器保持不变(即,仍然引用集合中的同一个对象,因为赋值的结果是同一个对象持有不同的值)。
#include <list>
#include <iostream>
class Box
{
private:
std::list <Box*>::iterator iter;
public:
static std::list <Box*> List;
Box() {
List.push_front(this);
iter = List.begin();
std::cout << "Constructing box." << std::endl;
}
~Box() {
std::cout << "Trashing box." << std::endl;
List.erase(iter);
}
void lookInside() {
std::cout << "It's empty." << std::endl;
};
// JVC: added next two overloads:
Box &operator=(Box const &src) {
// don't assign anything.
return *this;
}
Box(Box const &other) {
List.push_front(this);
iter = List.begin();
std::cout << "Copy constructing box.n";
}
};
std::list <Box*> Box::List;
int main()
{
Box Box_1;
Box Box_2;
Box Box_3;
Box_1 = Box_2; // No longer causes problem!
for (auto iter : Box::List) {
iter->lookInside();
}
std::cout << "The list contains " << Box::List.size() << " boxes." << std::endl;
return 0;
}
作为题外话:整个设计可能是一个错误。上面的代码在相对微观的层面上覆盖了bug,但没有纠正设计的基本问题。
相关文章:
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- 如何为包含另一个类实例的数组制作常量 getter?
- 我应该如何为包含动态数组的类编写所需的构造函数
- 标头包含不是 .c 程序所必需的,而是.cpp程序需要的
- 包含不同大小静态数组的类的多个实例
- 在C++中,为什么仅包含与其基类实例的联合的派生类占用的内存多于联合的大小?
- 无法编译包含"if constexpr"的函数模板实例化
- 如何在cython中包含C++所需的路径
- 当我无法包含代码所需的头文件时,如何链接 shrared 库?
- 如何操作包含"unique_ptr"的类的实例?
- 包含另一个实例的特征实例,该实例持有固定大小的特征对象
- 调用包含所有所需代码的函数或内部包含所需代码的其他函数的函数更好?
- 使一个标头成为多个类包含所必需的
- 如何在C++中仅包含一个实例创建类
- 包含自身实例化的模板,C++中的递归
- C++:包含类实例的并集调用了错误的虚拟函数
- 删除包含其他实例的实例的操作符
- 创建一个类,其静态成员容器包含所述类的所有实例