带有map的c ++ Singleton导致“违规读取位置”

时间:2014-01-30 01:38:58

标签: c++ singleton

我试图创建一个单例来访问类似全局的类。除非我在里面使用std::map,否则这个类很有效。

(是的,我知道,将方法放在.h ...中,但它用于调试):

panthera.h

class Panthera
{
private:
    std::map<std::string, std::map<long, Object *>> entities;

public:
    Panthera(void);
    ~Panthera(void);

    static Panthera * GetInstance()
    {
    static Panthera *engine_ = new Panthera();
    return engine_;
    }

    void Run() {std::cout << "I run" << std::endl;}
    void DOESNOTWORK(Object *o) {this->entities["test"][0] = o;}
};

的main.cpp

Panthera::GetInstance()->Run(); // no problem
Panthera::GetInstance()->DOESNOTWORK(); // access violation

现在试图解决这个问题一段时间......任何线索?



在使用OneonOne查看事物之后,我明白问题是类Object(如果我将它替换为空类,它会起作用)

试图在这个类中寻找不连贯/其他但是找不到问题的根,所以这里是类

Object.h

#pragma once

#include "Vector2.h"
#include <list>

class Object
{
protected:
    Vector2 location;
    float rotation;
    std::string plane;
    unsigned long id;

    std::list<Object *> children;

public:
    Object(void);
    Object(Vector2 const & location, std::string const & plane = "background", float rotation = 0);
    Object(Object const & other);

    ~Object(void);

public:
    virtual void SetLocation(Vector2 const & location);
    virtual Vector2 GetLocation() const;

    virtual void SetRotation(float);
    virtual float GetRotation() const;

    virtual void Move(Vector2 const & displacement);
    virtual void Rotate(float angle);

    virtual void Adopt(Object * other, Vector2 const & mountPoint = Vector2());
    virtual Vector2 Mount(Vector2 const & other) const;

    std::string GetPlane() const;
    long GetId() const;
};

实现是微不足道的,当它在std::map中添加时,类本身运行良好,除了单个...

像往常一样,提前感谢您的任何帮助(并询问您是否需要源文件(或Vector2类))



根据要求,Object.cpp文件

#include "Object.h"
#include "Matrix.h"
#include "Panthera.h"

Object::Object(void): location(Vector2()), rotation(0), plane("background")
{
    this->id = reinterpret_cast<long>(this);
    Panthera::GetInstance()->DOESNOTWORK(this);
}

Object::Object(Vector2 const & location, std::string const & plane, float rotation): location(location), rotation(rotation), plane(plane)
{
    this->id = reinterpret_cast<long>(this);
    //Panthera::GetInstance().Add(this);
}

Object::Object(Object const & other)
{
    *this = other;
    this->id = reinterpret_cast<long>(this);
    // Panthera::GetInstance().Add(this);
}

Object::~Object(void)
{
}

void Object::SetLocation(Vector2 const & location)
{
    this->Move(location - this->location);
}

Vector2 Object::GetLocation() const
{
    return this->location;
}

void Object::SetRotation(float rotation)
{
    this->Rotate(rotation - this->rotation);
}

float Object::GetRotation() const
{
    return this->rotation;
}

void Object::Move(Vector2 const & displacement)
{
    std::list<Object *>::iterator it;

    for (it = this->children.begin() ; it != this->children.end(); ++it)
    {
        (*it)->Move(displacement);
    }
    this->location += displacement;
}

void Object::Rotate(float angle)
{
    std::list<Object *>::iterator it;

    for (it = this->children.begin() ; it != this->children.end(); ++it)
    {
        (*it)->SetLocation(Matrix::Transform((*it)->GetLocation() - this->location, angle) + this->location);
    }
    this->rotation += angle;
}

void Object::Adopt(Object * other, Vector2 const & mountpoint)
{
    other->SetLocation(this->Mount(Matrix::Transform(mountpoint, this->rotation)));

    this->children.push_back(other);
}

Vector2 Object::Mount(Vector2 const & other) const
{
    return Vector2(this->location + other);
}

std::string Object::GetPlane() const
{
    return this->plane;
}

long Object::GetId() const
{
    return this->id;
}


更新:只是调用Object的构造函数失败。由于某种原因,它不允许我在他的构造函数中使用单例,=&gt;这是问题的根源


已解决:问题是在单例类中有一个Object,Object构造函数在初始化之前使用了单例。

1 个答案:

答案 0 :(得分:0)

您的代码甚至无法编译,因为您的构造函数和Destruct未实现。

这是一个C ++ 11版本:

#include <unordered_map>
#include <iostream>
#include <string>
class Object {};

class Panthera {
private:
    std::unordered_map<std::string, std::unordered_map<long, Object *>> entities;
    Panthera() noexcept {}

public:

    static Panthera & GetInstance() noexcept {
        static Panthera engine_;
        return engine_;
    }

    void Run() {std::cout << "I run" << std::endl;}
    void worksnow() {this->entities["test"][0] = new Object;}
    void get_test() {
        std::cout << this->entities["test"].size() << std::endl;
    }
};

int main() {
    Panthera::GetInstance().Run(); // no problem
    Panthera::GetInstance().worksnow(); //works too
    Panthera::GetInstance().get_test();
    return 0;
}

测试:

|---> clang++ -std=c++11 -stdlib=libc++ -lc++abi -I. test-singleton.cpp  && ./a.out 
I run
1

原始代码适用于我,因此您的问题与编译器相关或使用省略的代码:

#include <iostream>
#include <string>
#include <map>
class Object {};

class Panthera {
    private:
        std::map<std::string, std::map<long, Object *> > entities;
    public:
        Panthera(void) {}
        ~Panthera(void) {}

    static Panthera * GetInstance() {
        static Panthera *engine_ = new Panthera();
        return engine_;
    }

    void Run() {std::cout << "I run" << std::endl;}
    void DOESNOTWORK() {
        this->entities["test"][0] = new Object;
        std::cout << this->entities["test"].size() << std::endl;
    }
};

int main() {

    Panthera::GetInstance()->Run(); // no problem
    Panthera::GetInstance()->DOESNOTWORK(); // access violation
    return 0;
}