了解类对象

时间:2019-06-21 12:50:55

标签: c++ class oop object

我正在尝试创建将使用指针存储在矢量中的对象

当我不使用指针时,我可以在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;
}

我想将对象存储在矢量中,相反,我只能从指针中获得一些内存位置,但是如何存储对象而不是地址

3 个答案:

答案 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);

无需致电newdelete

但是,看起来您根本不需要指针。您可以只使用此答案开头所示的值类型。

答案 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