我有一个联盟,球队和球员的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时,玩家不再存储更多信息。那时的输出很神秘。
答案 0 :(得分:2)
首先,您按价值传递std::vector<Player>
。您可能打算通过引用传递它,否则您对它所做的任何更改都将丢失。
关于您的具体问题,您的“另一种方式”看起来几乎正确,但您正在存储指向团队向量中的本地player
变量的指针。当本地player
超出范围时,此指针将保持悬空状态。你需要在玩家矢量中存储一个指向玩家副本的指针,因为这是玩家所拥有的。
但是,正如您所发现的那样,即使这样也行不通,因为当在push_back
期间重新分配播放器向量时,所有指向向量元素的指针都将失效。您可以提前reserve
在播放器向量中所需的所有空间,以确保不会发生重新分配,但您可能不知道reserve
有多少空间。您可以使用不同的STL容器,如std::list
,它承诺指针不会失效。但是如果您不想在容器选择上妥协,我建议您在堆上创建播放器对象,并使用智能指针来管理内存,std::shared_ptr
或std::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));