在数据读入函数中的向量中存储指针

时间:2014-03-15 17:10:15

标签: c++ pointers boost

我有一个联盟,球队和球员的txt文件,如下所示:

League: some league

Team:  some team

some players with name and strength

League: some other league

现在我用readin函数读取数据

#include "ReadIn.h"
#include "Player.h"
#include <deque>
#include <fstream>
#include <string>
#include <sstream>
#include <memory>
#include <iostream>


std::string zeile,word1, word2, sname, lname;
std::deque<Team*> Teamvector;
int str, a = 0, b = 0 , c = 0;
using namespace std;

void readin_fillVector(std::deque<Team> &v, std::deque<League> & w, std::vector<Player> u) {
    ifstream fin("C:\\Users\\david\\Documents\\Visual Studio 2013\\Projects\\Anstoss2014\\Datenbank\\test.txt");

    //Einlesen der Zeilen starten
    while (getline(fin, zeile))
    {

        fin >> word1;
        //find out if this line contains the team name or the players
        if (word1 == "Liga:"){
            getline(fin, word2);
            //deleting the empty space in front of the team name
            word2.erase(0, 1);
            w.push_back(League(word2, c));
            c++;
        }
        else if (word1 == "Verein:"){
            getline(fin, word2);
            //deleting the empty space in front of the team name
            word2.erase(0, 1);
            v.push_back(Team(word2, a));

            //League gets the new member ( the team which was read in the line before)
            w.back().AddTeam(&v.back());
            //Team gets an pointer to the league it plays in
            v.back().SetLeague(&w.back());
            a++;
        }
        else{
            fin >> lname >> str;
            Player* player = new Player();
            player->setinformation_(b, word1, lname, str, &v.back());
            u.push_back(*player);
            v.back().AddPlayer(player);
            //for (size_t f = 0; f < v.back().GetPlayerList().size(); f++)
            //{
            //  v.back().GetPlayerList()[f]->getinformation_();
            //}
            b++;

        }

    }

}

这样就可以了,但我对这行

感到困惑
Player* player = new Player();

我读了很多关于指针的内容,并且有人说应该以某种方式删除由new()创建的这个播放器。所以第一个问题是:1。这是对的吗?

但是如果我在我的功能中执行此操作,则存储在团队的playervector中的玩家信息将丢失。

2.我有提升可访问性,我应该使用像boost :: ptr_vector这样的东西吗?

3.如果没有,我还能做些什么来避免内存泄漏?

修改

我试过的另一种方式是

Player player;
player.setinformation_(b, word1, lname, str, &v.back());
u.push_back(player);
v.back().AddPlayer(&player);

但是当这个函数返回teamvector时,玩家不再存储更多信息。那时的输出很神秘。

1 个答案:

答案 0 :(得分:2)

首先,您按价值传递std::vector<Player>。您可能打算通过引用传递它,否则您对它所做的任何更改都将丢失。

关于您的具体问题,您的“另一种方式”看起来几乎正确,但您正在存储指向团队向量中的本地player变量的指针。当本地player超出范围时,此指针将保持悬空状态。你需要在玩家矢量中存储一个指向玩家副本的指针,因为这是玩家所拥有的。

但是,正如您所发现的那样,即使这样也行不通,因为当在push_back期间重新分配播放器向量时,所有指向向量元素的指针都将失效。您可以提前reserve在播放器向量中所需的所有空间,以确保不会发生重新分配,但您可能不知道reserve有多少空间。您可以使用不同的STL容器,如std::list,它承诺指针不会失效。但是如果您不想在容器选择上妥协,我建议您在堆上创建播放器对象,并使用智能指针来管理内存,std::shared_ptrstd::unique_ptr。所以函数原型看起来像:

in_fillVector(std::deque<Team> &v, std::deque<League> & w, std::vector<std::unique_ptr<Player>> &u) 

添加玩家看起来像:

auto player = std::unique_ptr<Player>(new Player());
player->setinformation_(b, word1, lname, str, &v.back());
v.back().AddPlayer(player.get());
u.push_back(std::move(player));