gpt4 book ai didi

c++ - 创建一个带有静态成员容器的类,其中包含该类的所有实例?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:21 25 4
gpt4 key购买 nike

我的目标是创建一个类,它将从它创建的每个实例添加到静态成员容器中,以便可以轻松访问所有实例。

上下文是一个游戏,其中对象在 Game.init() 函数中创建,然后添加到容器中。 Game.update()Game.Draw() 函数然后遍历容器以访问和操作对象。

我希望构造函数和析构函数能够处理这些任务,而不是手动将对象添加到容器或从容器中移除对象。

当对象(此代码中的框)被复制或分配时,指针变得无效,这是有问题的。使用对象容器而不是指向对象的指针容器会导致生成过多的拷贝,而且我无法使用引用来实现这一点。我正在寻找有关如何改进此代码以避免这些问题的一些提示(不需要使用指向对象容器的指针,事实上我更愿意避免使用指针但没有设法使它工作他们):

#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;
}

最佳答案

你违反了三/五规则。

毫无疑问,您将需要重载赋值和复制构造(至少)以使您的类(class)按预期工作。默认的复制构造函数将只复制迭代器,因此您最终会得到第二个对象,其中包含原始迭代器的拷贝,指向原始对象,因此当任一拷贝被销毁时,该项目将从您的集合中删除。

显然,您想要的是向集合中添加一个新对象,并让该对象在复制构造完成后将迭代器保存到集合中的新对象。

同样,默认赋值运算符会将迭代器从源复制到目标。您可能只想保持迭代器不变(即,仍然引用集合中的同一个对象,因为赋值导致同一个对象持有不同的值)。

#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;
}

顺便说一句:整个设计可能是个错误。上面的代码在相对微观层面上涵盖了错误,但没有解决设计的基本问题。

关于c++ - 创建一个带有静态成员容器的类,其中包含该类的所有实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16501419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com