c++:跟踪所有现有对象
c++: Keeping track of all existing objects
我需要跟踪特定类创建的所有对象,并且需要使用标识符字符串访问它们。下面的代码几乎正是我所需要的。类NamedObject有一个静态成员m_object_by_name,它将名称(字符串)映射到对象,构造函数将每个创建的对象添加到映射中,析构函数从映射中删除删除的对象。
#include <map>
#include <string>
#include <iostream>
using namespace std;
class NamedObject
{
public:
static NamedObject *object_by_name(const string &name) {
return m_object_by_name[name];
}
NamedObject(const string &name) : m_name(name) {
m_object_by_name[m_name] = this;
}
~NamedObject() {
m_object_by_name.erase(this->m_name);
}
const string &name() const{
return m_name;
}
private:
string m_name;
static map<string, NamedObject *> m_object_by_name;
};
map<string, NamedObject *> NamedObject::m_object_by_name;
int main ()
{
new NamedObject("name1");
new NamedObject("name2");
NamedObject *obj1 = NamedObject::object_by_name("name1");
NamedObject *obj2 = NamedObject::object_by_name("name2");
cout << obj1->name() << endl;
cout << obj2->name() << endl;
}
现在我有几个类,它们的对象需要通过名称来访问。从上面的NamedObject类继承当然存在这样的问题,即所有这些类都会共享它们的名称(例如,我不能有两个不同类但名称相同的对象),因为它们共享映射m_objects_by_name。此外,当使用object_by_name()方法访问对象时,我总是必须从NamedObject转换为实际的类。
我目前使用的这个问题的解决方案可以在下面的代码中看到。然而,我对这个解决方案并不满意(见下面的评论)。模板类NamedObjectStore现在负责存储类T的所有对象。此外,还有一个基类处理具有名称的属性和真正使用的派生类。派生类有一个静态NamedObjectStore对象,它在创建时添加对象,在删除时删除对象。
#include <map>
#include <string>
#include <iostream>
using namespace std;
template <class T>
class NamedObjectStore
{
public:
void add_object(T *obj) {
m_object_by_name[obj->name()] = obj;
}
void rem_object(T *obj) {
m_object_by_name.erase(obj->name());
}
T *object_by_name(const string &name) {
return m_object_by_name[name];
}
private:
map<string, T *> m_object_by_name;
};
class BaseNamedObject
{
public:
BaseNamedObject(const string &name) : m_name(name) {
}
const string &name() const {
return m_name;
}
private:
string m_name;
};
class DerivedNamedObject : public BaseNamedObject
{
public:
static NamedObjectStore<DerivedNamedObject> store;
DerivedNamedObject(const string &name) : BaseNamedObject(name) {
store.add_object(this);
}
~DerivedNamedObject() {
store.rem_object(this);
}
};
NamedObjectStore<DerivedNamedObject> DerivedNamedObject::store;
int main ()
{
new DerivedNamedObject("name1");
new DerivedNamedObject("name2");
DerivedNamedObject *obj1 = DerivedNamedObject::store.object_by_name("name1");
DerivedNamedObject *obj2 = DerivedNamedObject::store.object_by_name("name2");
cout << obj1->name() << endl;
cout << obj2->name() << endl;
}
从积极的方面来说,使对象成为命名对象(即name()-函数)的实现是在基类BaseNamedObject中完成的。此外,存储所有对象的结构的实现位于NamedObjectStore类中,并隐藏在其方法后面。这使我可以根据需要轻松地更改这两种实现,而无需接触所有派生类。
消极的一面是,我仍然需要一遍又一遍地打同样的东西。更准确地说,对于每个派生类(如DerivedNamedObject),我必须声明和定义静态成员存储,我必须在构造函数中向存储添加对象,并在析构函数中从存储中删除它们。
所以我的问题来了:有更好的方法来解决这个问题吗?还是我必须在每个派生类中使用这四行代码?
希望得到一些鼓舞人心的建议:-)
Thomas
正如我的评论中所说,您可以使用奇怪的重复模板模式来解决这个问题。下面的代码使用您的原始示例,以实际存储的类型为模板:
#include <map>
#include <string>
#include <iostream>
using namespace std;
template<class T>
class NamedObject
{
public:
static NamedObject *object_by_name(const string &name) {
return m_object_by_name[name];
}
NamedObject(const string &name) : m_name(name) {
m_object_by_name[m_name] = this;
}
virtual ~NamedObject() {
m_object_by_name.erase(this->m_name);
}
const string &name() const{
return m_name;
}
private:
string m_name;
static map<string, NamedObject *> m_object_by_name;
};
template <class T>
map<string, NamedObject<T> *> NamedObject<T>::m_object_by_name;
class A : public NamedObject<A>
{
public:
A(const std::string& name) : NamedObject(name)
{}
};
class B : public NamedObject<B>
{
public:
B(const std::string& name) : NamedObject(name)
{}
};
int main()
{
new A("Test");
new B("Test");
auto one = A::object_by_name("Test");
auto two = B::object_by_name("Test");
cout << one << " - " << one->name() << "n";
cout << two << " - " << two->name() << "n";
delete two;
delete one;
}
- C++:跟踪类对象
- MATLAB:跟踪imufilter对象中的状态变化
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- 内存分配究竟是如何发生的,Java和C如何交互以跟踪同一对象?
- 如何在类中声明一个变量,该变量将跟踪已创建 c++ 的对象计数
- 从实时摄影机馈送而不是图像中按形状跟踪对象
- 如何清理本地引用中跟踪C++对象<External>?
- 如何确定我跟踪的对象球是否越过我绘制的线
- 跟踪对象类型
- 丢失后再次找到的对象跟踪
- 使用本地二进制模式进行对象跟踪:更改检测ROI的大小
- OpenCV C++简单的对象跟踪
- opencv 卡尔曼滤波多对象跟踪错误
- 使用开放CV进行对象跟踪
- 增强序列化-启用对象跟踪
- 实现对象跟踪,如在 Boost::Serialization 中
- 如何在opencv中使用对象跟踪的概念移动鼠标
- Opencv对象跟踪和计数在视频帧中通过ROI的对象
- 使用OpenCV的对象跟踪脚本中的慢速视频
- OpenCV中鸟瞰中的实时对象跟踪