c ++如何释放对外部对象的静态引用?

时间:2014-12-20 00:37:22

标签: c++ c++11 static-members

首先,您需要查看此代码,此处我有两个类 - 一个是TreasureBag,另一个是Sprite。我有精灵的多个副本,但只有一个包(因此它是static)。精灵获得了包并收集宝藏,存放在里面,然后下一个精灵来用它来收集宝藏。

这是我的代码 -

class TreasureBag {
    private:
        int* bag ; int size ; int index ;

    public:
        TreasureBag(int size = 10) {
            this->index = 0 ; this->size = size ;
            this->bag = new int[this->size] ;
        }
        ~TreasureBag() { delete [] this->bag ; }
        void put(int data) { this->bag[this->index++] = data ;}
        friend ostream& operator<< (ostream &os, const TreasureBag &tb);
};

class Sprite 
{
    private:
        static TreasureBag tbag ; int points = 0 ; string name ;

    public:
        Sprite(string name) { this->name = name ; }
        ~Sprite() { ; } // --> not sure what to do here
        void collect(int data) { this->tbag.put(data); }
        void acquireTreasureBag(TreasureBag &tb) { Sprite::tbag = tb ; }
        void releaseTreasureBag() { ; } // ---> not sure what to do here either
        friend ostream& operator<< (ostream& os, const Sprite &s);
};
TreasureBag Sprite::tbag ;

在主要内部,我有两个精灵s1和s2,以及一个宝藏包。精灵s1先来,抓住它并把东西放进去,然后它releases包和s2获得它。

int main()
{
    TreasureBag tb(5) ; Sprite s1("s1");
    s1.acquireTreasureBag(tb); // <-- Looks like this line is problematic

    /*s1.collect(1); s1.collect(2);
    cout << s1 << endl ;
    s1.releaseTreasureBag();

    Sprite s2("s2"); s2.acquireTreasureBag(tb);
    s2.collect(3);
    cout << s2 << endl ;*/
    return 0 ;
}

但是当我运行代码时(请参阅未注释的行),我收到此错误 -

*** Error in `./a.out': double free or corruption (fasttop): 0x0000000002495040 ***
Aborted (core dumped)

处理这种情况的最佳方法是什么?我的设计原则好吗?此外,我不确定在sprite析构函数~Sprite()releaseTreasureBag()过程中应该做些什么。

请帮忙。

2 个答案:

答案 0 :(得分:3)

你不尊重三(或五)的规则。 使用std::vector来避免自己管理内存:

class TreasureBag {
private:
    std::vector<int> bag;
    int max_size;

public:
    TreasureBag(int size = 10) : max_size(size) {}
    void put(int data) { if (bag.size() < max_size) bag.push_back(data) ;}
public:
    friend ostream& operator<< (ostream &os, const TreasureBag &tb);
};

答案 1 :(得分:1)

您似乎可能想要使用智能指针:

class Sprite {
    static std::shared_ptr<TreasureBag> tbag;

public:
    void acquire(std::shared_ptr<TreasureBag> tb) {
        tbag = tb;
    }

    void release() {
        tbag.reset();
    }
};

然后将TreasureBag构建为shared_ptr

std::shared_ptr<TreasureBag> tb = std::make_shared<TreasureBag>(5);
Sprite s1("s1");
s1.acquire(tb);