在类中使用静态集合来存储类
Use of static collections within a class to store class
我正在检查一些代码,我看到的一个常见模式是将对象集合存储为正在存储的对象类的静态成员。
例如,如果我有一个object类:class widget,那么widget列表将作为静态std::列表存储在widget类中。
要做到这一点,最明显的方法是有一个应用程序级别(全局级别)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 ") << "foundn";
// 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 " : "") << "foundn";
return 0;
}
除了一些简单的情况外,它并不更方便。添加实例的静态映射意味着添加了一个隐藏的依赖项。是否存在不需要此列表的用例?如果你把它作为一个静态私有实例,你将永远拥有它(不管你是否使用它)。我可以看到静态成员集合的思想对于a的用户来说更方便。
同样,您编写的代码将在这里产生意想不到的结果:
class a::id2a_map : public std::map<int, a*>
std::map不是为继承而写的,这意味着它没有虚析构函数。当类被销毁时,它的析构函数可能不会被调用(依赖于编译器)。
是否有其他类似的替代方案?a和b方法的优缺点是什么?
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
在静态成员的情况下,如果您有静态方法对它们做一些事情,因为编译器在编译时知道所有这些方法将做什么,所以它有更好的机会很好地优化它们。根据编译器的不同,优化的数量也不同。
这是一个有趣的讨论:http://bytes.com/topic/c/answers/617238-static-functions-better-optimized-compilers
相关文章:
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 是否有用于存储离散间隔的集合
- 如何添加到已存储在集合中的集合
- 我可以在不手动将它们分配在堆上的情况下存储iostreams集合
- 存储文件c++中的集合
- 将索引存储在向量<集合<int>>与向量<向量中<int>>
- 可用于存储和管理整数集合的最佳C++数据结构是什么
- 集合差分的输出可以存储在第一个输入中
- 可以在C++中更改存储在集合中的对象的非关键部分.如何在java中进行类似操作
- 如何在没有临时设置的情况下将集合差异 s1-s2 存储在 s1 中
- 在集合中正确存储QFiles
- 关于在 c++ 中将文件路径存储在集合 STL 中
- 如何在 Map 中存储集合容器的迭代器列表
- 包含具有 CString 成员变量的类的集合仅存储第一个字母
- 将元素存储在具有两个可能索引的集合中
- C++在一个集合中存储多个数据类型
- 我可以使用提升池作为存储来支持提升侵入式集合吗
- 如何搜索字符串是否是存储在集合中的字符串的前缀
- 集合类型:如何存储bool、string类型的列表
- C++类(带集合)存储一个通用模板类..编译问题