gpt4 book ai didi

c++ - 在类中使用静态集合来存储类

转载 作者:行者123 更新时间:2023-11-28 07:00:40 28 4
gpt4 key购买 nike

我正在审查一些代码,我看到的一个常见模式是将对象集合存储为所存储对象类的静态成员。

例如,如果我有一个对象类:小部件类,那么小部件列表将作为静态 std::list 存储在小部件类中。

执行此操作的明显方法是拥有应用程序级别(全局级别)std::list - 然后查找此应用程序级别列表中的项目。

可以看出静态成员集合的思路对于a的用户来说还是比较方便的。还有其他优势吗?是否还有其他类似的替代方案? a 和 b 方法的优缺点是什么?

下面是代码中的两个备选方案:

file a.hpp:
//Using collection as static member of class idea
class a {
public:
a();
~a();
class id2a_map;
static class id2a_map id_map;
static a* Find(unsigned id);

unsigned m_id;
};

file a.cpp:
#include <map>
#include "a.hpp"

class a::id2a_map : public std::map<int, a*>
{
};

a::id2a_map a::id_map;

a::a() {
static unsigned id_cnt = 0;
++id_cnt;
id_map.insert(id_map.end(), id2a_map::value_type(m_id = id_cnt, this));
}

a::~a() {
id_map.erase(m_id);
}

a* a::Find(unsigned id) {
id2a_map::iterator i = id_map.find(id);
return i==id_map.end() ? 0 : i->second;
}


file b.hpp:
// b class - not using static collection
class b {
public:
b(unsigned id) : m_id(id) { }
unsigned get_id() const { return m_id; }

private:
unsigned m_id;
};

file main.cpp to exercise a and b:
#include <iostream>
#include <map>
#include "a.hpp"
#include "b.hpp"

int main() {
// approach using static map within class
a obj1;
a obj2;
a obj3;
a obj4;

a* fnd = a::Find(2);
std::cout << "object with id 2 " << (fnd ? "" : "not ") << "found\n";

// application level map
std::map<unsigned, b*> id2b_map;
unsigned id = 0;
b obj5(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj5));
b obj6(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj6));
b obj7(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj7));
b obj8(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj8));

std::map<unsigned, b*>::iterator i = id2b_map.find(2);
std::cout << "object with id 2 " << (i == id2b_map.end() ? "not " : "") << "found\n";
return 0;
}

最佳答案

I can see that the static member collection idea is more convenient for the user of a.

不是更方便,除了简单的情况。添加实例的静态映射意味着您添加了隐藏的依赖项。当您不需要此列表时,是否有任何用例?如果您将它作为静态私有(private)实例放置,您将始终拥有它(无论您是否使用它)。

还有,你写的代码,在这里会产生意想不到的结果:

class a::id2a_map : public std::map<int, a*>

std::map 不是为继承而编写的,这意味着它没有虚拟析构函数。当类被销毁时,它的析构函数可能不会被调用(依赖于编译器)。

Are there other alternatives which should also be considered similar? What are the pros and cons of a and b approach?

B 方法更好,但没有达到应有的水平。实现将不依赖于 std::list(最小化依赖总是一个加号)但列表有指针,它不应该。

你能改写这样的东西吗?

class a {
public:
a();
~a();

unsigned m_id; // same as in your example
};

客户端代码:

std::map<unsigned, a> instances; // not static; if you need it somewhere else,
// just pass it in as a parameter

a instance;
instances[a.m_id] = std::move(a);
// use instances.find from here on

代码简单明了,极简且不会破坏 SRP。

关于c++ - 在类中使用静态集合来存储类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22536780/

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