0

如果有人问过这个问题,我深表歉意,我不确定如何用最好的词来形容它,也找不到它。

我基本上有一个类,我想维护一个自身的映射,并且该列表应该具有该对象的唯一实例。

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 声明为朋友

friend class unordered_map<Uint32, MyClass>;

然而,似乎没有更少的错误,我推测这是由于 unordered_map 使用的类,如pair和hash。所以我的问题是是否有替代方案。我应该只声明更多似乎从编译器中出错的朋友,还是有另一种方法?

4

2 回答 2

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());
}
于 2014-08-19T01:41:14.353 回答
1

更新: TC 好心地指出了我忽略的几件事,所以这个答案完全改变了......

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

以上代码位于 ideone.com

根据评论,标准没有记录必要的友谊列表,因此可能会因新编译器版本或移植到另一个编译器而中断。

或者,您可以将(智能)指针存储在unordered_map.

于 2014-08-19T02:27:08.797 回答