C ++矢量对象超出范围

时间:2021-12-05 21:17:41

I'm having trouble understanding how to properly build a vector of pointers (I'm pretty new to C++). I think the following code summarizes the problem:

我无法理解如何正确构建指针向量(我对C ++很新)。我认为以下代码总结了这个问题:

Mok.h

class Mok
{
public:
    Mok(int n) : m_num{n}
    int getNum() {return m_num}
private:
    int m_num;
};

Bar.h

class Bar
{
public:
    Bar();

    void setTiles();
    void printTiles();

private:
    std::vector<Mok*> m_tileSet;
};

Bar.cpp

void Bar::setTiles()
{
    for (int i = 0; i < 4; ++i)
    {
        m_tileSet.push_back(&Mok(i));
    }
}

void Bar::printTiles()
{
    for (const auto &mok : m_tileSet)
    {
        std::cout << mok->getNum() << " ";
    }
}

The idea would be to print the numbers stored in the vector, but instead I get crazy numbers (I know it doesn't make much sense for ints, the real code is more complex, this is a simplification. Imagine Mok as a big object, and the vector containing thousands of objects). Inside setTiles() everything seems to get stored ok (VS debugger says so), but when I get to printTiles(), the information is lost and I get numbers like -858993460.

想法是打印存储在矢量中的数字,但我得到了疯狂的数字(我知道它对于整数没有多大意义,真正的代码更复杂,这是一个简化。想象莫克作为一个大对象,以及包含数千个对象的向量)。在setTiles()里面,一切似乎都存储好了(VS调试器这样说),但是当我到printTiles()时,信息丢失了,我得到的数字像-858993460。

I guess the Mok objects are going out of scope, so the references (edit: I mean addresses) start pointing nowhere? What would be the way to do this?

我猜Mok对象超出了范围,所以引用(编辑:我的意思是地址)开始指向哪里?这样做的方法是什么?

Thanks! :)

1 个解决方案

#1


0  

As Sam and Chris suggested in the comments, one way is to avoid using a pointer. The following code works:

正如Sam和Chris在评论中建议的那样,一种方法是避免使用指针。以下代码有效:

Mok.h

class Mok
{
public:
    Mok(int n) : m_num{n}
    int getNum() {return m_num}
private:
    int m_num;
};

Bar.h

class Bar
{
public:
    Bar();

    void setTiles();
    void printTiles();

private:
    std::vector<Mok> m_tileSet;
};

Bar.cpp

void Bar::setTiles()
{
    for (int i = 0; i < 4; ++i)
    {
        m_tileSet.push_back(Mok(i));
    }
}

void Bar::printTiles()
{
    for (auto &mok : m_tileSet)
    {
        std::cout << mok.getNum() << " ";
    }
}

Keeping the pointer, using std::unique_ptr (thanks to n.m. in the comments):

保持指针,使用std :: unique_ptr(感谢评论中的n.m.):

Bar.h

class Bar
{
public:
    Bar();

    void setTiles();
    void printTiles();

private:
    std::vector<std::unique_ptr<Mok>> m_tileSet;
};

Bar.cpp

void Bar::setTiles()
{
    for (int i = 0; i < 4; ++i)
    {

        m_tileSet.push_back(std::make_unique<Mok>(i)); // C++14
        //m_tileSet.push_back(std::unique_ptr<Mok>(new Mok(i))); // Previous to C++14
    }
}

void Bar::printTiles()
{
    for (auto &mok : m_tileSet)
    {
        std::cout << mok->getNum() << " ";
    }
}

#1


0  

As Sam and Chris suggested in the comments, one way is to avoid using a pointer. The following code works:

正如Sam和Chris在评论中建议的那样,一种方法是避免使用指针。以下代码有效:

Mok.h

class Mok
{
public:
    Mok(int n) : m_num{n}
    int getNum() {return m_num}
private:
    int m_num;
};

Bar.h

class Bar
{
public:
    Bar();

    void setTiles();
    void printTiles();

private:
    std::vector<Mok> m_tileSet;
};

Bar.cpp

void Bar::setTiles()
{
    for (int i = 0; i < 4; ++i)
    {
        m_tileSet.push_back(Mok(i));
    }
}

void Bar::printTiles()
{
    for (auto &mok : m_tileSet)
    {
        std::cout << mok.getNum() << " ";
    }
}

Keeping the pointer, using std::unique_ptr (thanks to n.m. in the comments):

保持指针,使用std :: unique_ptr(感谢评论中的n.m.):

Bar.h

class Bar
{
public:
    Bar();

    void setTiles();
    void printTiles();

private:
    std::vector<std::unique_ptr<Mok>> m_tileSet;
};

Bar.cpp

void Bar::setTiles()
{
    for (int i = 0; i < 4; ++i)
    {

        m_tileSet.push_back(std::make_unique<Mok>(i)); // C++14
        //m_tileSet.push_back(std::unique_ptr<Mok>(new Mok(i))); // Previous to C++14
    }
}

void Bar::printTiles()
{
    for (auto &mok : m_tileSet)
    {
        std::cout << mok->getNum() << " ";
    }
}