我正在尝试创建将使用指针存储在矢量中的对象
当我不使用指针时,我可以在vector中存储对象,但是当我尝试使用指针时,我不能这样做
// created class that combine some attributes for file "datum" = date, "vrijeme" = creation of file etc.
class datoteka{
public:
string datum;
string vrijeme;
string velicina;
string ime;
datoteka();
datoteka(string datum, string vrijeme, string velicina, string ime)
{
this -> datum = datum;
this -> vrijeme = vrijeme;
this -> velicina = velicina;
this -> ime = ime;
}
~datoteka();
};
int main()
{
vector <datoteka> fajlovi;
string linija;
string prva;
int i = 0;
datoteka * pokObjDatoteke;
pokObjDatoteke = new datoteka();
std::ifstream pisi("list.txt"); //file is open
while(getline(pisi,linija)) //get first line of file
{
string vrijednost;
stringstream red; //create stream from line
string datoteka[4]; // create array to store seperate information
red << linija;
while(!red.eof() && i != 4) // since line containt lot of tabs i
read just first for values
{
red >> vrijednost;
datoteka[i]= vrijednost;
i++;
cout << vrijednost << " ovo je vrijednost" << endl;
}
pokObjDatoteke->datum = datoteka[0];
pokObjDatoteke->vrijeme = datoteka[1];
pokObjDatoteke->velicina = datoteka[2];
pokObjDatoteke->ime = datoteka[3];
fajlovi.push_back(*pokObjDatoteke); /**** problem ****
}
return 0;
}
我想将对象存储在矢量中,相反,我只能从指针中获得一些内存位置,但是如何存储对象而不是地址
答案 0 :(得分:1)
此:
fajlovi.push_back(*pokObjDatoteke);
在向量中存储指向对象pokObjDatoteke
的副本。指向的对象随后泄漏,因为您从未删除它。
您是否真的需要这里的指针?向量包含值类型,而不包含指针,因此只需使用emplace_back
直接在向量中构造对象:
while (getline(pisi, linija))
{
string vrijednost;
stringstream red;
string datoteka[4];
red << linija;
while (!red.eof() && i != 4) {
red >> vrijednost;
datoteka[i]= vrijednost;
i++;
cout << vrijednost << " ovo je vrijednost" << endl;
}
fajlovi.emplace_back(datoteka[0], datoteka[1], datoteka[2],
datoteka[3]);
}
但是,如果您真的要在向量中使用指针,则可以这样声明:
vector <datoteka*> fajlovi;
,然后将原始代码中的push_back
调用更改为:
fajlovi.push_back(pokObjDatoteke);
这会将指针推入向量。您需要记住在矢量被销毁时将其删除,否则所有对象将被泄漏:
for (auto* obj : fajlovi) {
delete obj;
}
像这样的手动内存管理容易出错并且令人头疼。不要这样请改用智能指针,例如shared_ptr
。删除原始代码中的这些行:
vector <datoteka> fajlovi;
// ...
datoteka * pokObjDatoteke;
pokObjDatoteke = new datoteka();
并替换为:
#include <memory>
// ...
vector <shared_ptr<datoteka>> fajlovi;
// ...
auto pokObjDatoteke = make_shared<datoteka>();
,然后用push_back
:
fajlovi.push_back(pokObjDatoteke);
无需致电new
或delete
。
但是,看起来您根本不需要指针。您可以只使用此答案开头所示的值类型。
答案 1 :(得分:0)
如果要存储对象,那么为什么要使用指针?
datoteka pokObjDatoteke;
while (...)
{
...
pokObjDatoteke.datum = datoteka[0];
pokObjDatoteke.vrijeme = datoteka[1];
pokObjDatoteke.velicina = datoteka[2];
pokObjDatoteke.ime = datoteka[3];
fajlovi.push_back(pokObjDatoteke);
}
为什么您要尝试在不使用指针的情况下使用指针?
答案 2 :(得分:0)
虽然OP没有公开输入文件的示例,但此行(除了其他答案中指出的所有问题)似乎可疑
while(!red.eof() && i != 4) {...}
例如参见Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
更好的模式是执行提取,然后然后检查是否成功。
while( some_stream >> some_data ) {...}
OP的代码可以改写成这样
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
class datum
{
std::string a_, b_, c_, d_;
public:
datum() = default;
datum(std::string const &a, std::string const &b, std::string const &c, std::string const &d)
: a_(a), b_(b), c_(c), d_(d)
{}
friend std::istream &operator>> (std::istream &is, datum &obj)
{
return is >> obj.a_ >> obj.b_ >> obj.c_ >> obj.d_;
}
friend std::ostream &operator<< (std::ostream &os, datum const &obj)
{
return os << "a: '" << obj.a_ << "', b: '"<< obj.b_
<< "', c: '" << obj.c_ << "', d: '" << obj.d_ << '\'';
}
};
int main()
{
std::vector<datum> data;
std::ifstream in_stream {"list.txt"};
if ( !in_stream )
{
std::cout << "Error: unable to open input file.\n";
return -1;
}
std::string line, junk;
while(getline(in_stream, line))
{
// This won't consider an error to have empty lines in the file
if (line.empty())
continue;
std::istringstream iss(line);
datum dd;
iss >> dd;
// Stops if there are more or less strings than required in the line
if ( !iss or iss >> junk)
break;
data.push_back(std::move(dd));
}
for (auto const & d : data)
std::cout << d << '\n';
}
可测试的here。