如果有人问我,我很抱歉,我不确定如何用最好的词来表达它。
我本质上有一个类,我想维护一个自己的地图,该列表应该只有对象的实例化。
using std::unordered_map;
class MyClass
{
~MyClass() {};
MyClass() {}; // these actually contain code which operate on the classes data
static unordered_map<Uint32, MyClass> list;
public:
static const MyClass& GetObject(Uint32 key) {return list[key];};
};
当我编译我的代码时,它基本上给了我一堆来自STL的错误,说它调用了删除的函数等等,这是有道理的,因为unordered_map可能使用构造函数和析构函数,所以我声明unordered_map是朋友< / p>
friend class unordered_map<Uint32, MyClass>;
然而,似乎没有更少的错误,我推测这是由于unordered_map(如pair)和hash使用的类。所以我的问题是,如果有替代方案。我是否应该向编译器声明出现错误的朋友,或者是否有其他方法?
答案 0 :(得分:2)
因此。你有兴趣做一些烦人的事情。所以我们这样做吧。正如AlexD所说,你所缺少的是一个公共析构函数。 unordered_map需要访问它(可能通过一些实现定义的内部类)。
所以,让我们这样做,让我们做你应该做的事情,那就是做一个更小更简单的测试用例:
#include <unordered_map>
class MyClass {
public:
~MyClass() {}
private:
MyClass() {}
};
int main() {
std::unordered_map<int, MyClass> x;
x.at(3);
//x[3];
}
现在,请注意我已注释掉x[3]
。我们不能使用它。那是因为如果地图中不存在3,我们会调用MyClass
的默认构造函数,它是私有的。并且因为编译器在编译时不知道是否为真,所以需要确保它可以调用构造函数。
从评论中可以看出,您无法在此地图中插入任何对象。好吧,让我们添加一个静态工厂方法并摆脱这个问题:
#include <unordered_map>
using std::unordered_map;
class MyClass {
public:
static MyClass factory() { return MyClass(); }
~MyClass() {}
private:
MyClass() {}
int x;
};
int main() {
std::unordered_map<int, MyClass> x;
x.insert(std::make_pair(3, MyClass::factory()));
x.emplace(4, MyClass::factory());
}
答案 1 :(得分:1)
更新:T.C。我特别指出了一些我忽略的事情,所以这个答案完成了一个完整的面孔......
#include <iostream>
#include <unordered_map>
#include <map>
#include <cinttypes>
class MyClass
{
typedef std::unordered_map<uint32_t, MyClass> Instances;
friend Instances;
friend std::pair<uint32_t, MyClass>;
friend std::pair<const uint32_t, MyClass>;
public:
static const MyClass& getObject(uint32_t key) { return instances_[key] = 2 * key; }
~MyClass() {}
int n() const { return n_; }
private:
MyClass() : n_(-1) { }
MyClass& operator=(int n) { n_ = n; return *this; }
int n_;
static Instances instances_;
};
MyClass::Instances MyClass::instances_;
int main() {
const MyClass& m20 = MyClass::getObject(20);
const MyClass& m21 = MyClass::getObject(21);
std::cout << m20.n() << ' ' << m21.n() << '\n';
}
以上代码at ideone.com。
根据评论,标准没有记录必要的友谊列表,因此可能会破坏新的编译器版本或移植到另一个编译器。
Alterantively,您可以在unordered_map
中存储(智能)指针。