通过指向实例的静态指针访问成员变量

时间:2014-04-23 18:01:29

标签: c++ multithreading static

我有一个类,其中包含指向该类所有实例的指针的静态向量。当我通过静态getter方法访问成员变量时,我有时会得到错误的结果。

代码:
HPP-文件:

class ObjectID {
    public:
        ObjectID();
        float getShininess() const { return m_shininess; }
        static const std::shared_ptr<ObjectID> getID(unsigned long);
    private:
        float m_shininess;
        static std::vector<std::shared_ptr<ObjectID>> s_ids;
}

cpp-file:

static std::mutex s_mutex;
std::vector<std::shared_ptr<ObjectID>> ObjectID::s_ids = {};

const std::shared_ptr<ObjectID> ObjectID::getID(unsigned long id) {
    std::lock_guard<std::mutex> lock(s_mutex);
    std::shared_ptr<ObjectID> ptr = s_ids.at(id - 1);
    return ptr;
}

ObjectID::ObjectID()
  : m_shininess(50.f)
{
    std::lock_guard<std::mutex> lock(s_mutex);
    s_ids.emplace_back(this);
}

我怀疑它与我使用两个线程的事实有关。但是添加互斥锁并没有改变任何东西。

为了澄清,一个线程创建ObjectID,另一个线程调用

ObjectID::getID(id)->getShininess();

我并不总是得到50,有时候得到1,我永远不会改变m_shininess。 有什么想法吗?

修改

ObjectID在另一个类中创建,该类具有ObjectIDs的向量。

m_objects.emplace_back();

1 个答案:

答案 0 :(得分:2)

你的vector包含shared_ptr,但是你将ObjectID(this)的原始指针放入其中。由于shared_ptrs可以从原始构造中构建,因此可以编译,但它可能没有按照您的要求进行编译。特别是,如果ObjectID通过其他方式被破坏,您将在该向量中使用野生指针。我不确定这是你问题的原因,但至少是可疑的。

我不知道你的确切要求,但是这样的事情会有所帮助吗?

class ObjectID
{
public:
   static std::shared_ptr<ObjectID> Create()
   {
       auto created = std::make_shared<ObjectID>();
       s_ids.push_back(created);
       return created;
   }  

private:
   ObjectID()
   {
      // as before
   }
};