Как я могу прочитать файлы .txt, унаследованные объекты в C ++? - PullRequest
0 голосов
/ 12 мая 2019

Я выполняю задание, где мне нужно создать базу данных на c ++ для спортивной организации, без использования STL (я создал свой собственный список и String). База данных хранит данные в двусвязном списке, где помимо узлов есть данные, которые представляют собой команды. Конечно, есть не только один тип команд, в настоящее время есть три. Эти объекты унаследованы объектами команд. Я заставил все работать, кроме чтения текстового файла и создания объектов.

Я уже пытался создать маркер, который будет первым фрагментом информации, который программа прочитает, который решит, какой из трех классов должен быть создан, а затем прочитает другие данные, чтобы создать новый объект, затем поместите его в конец двусвязного списка. К сожалению, он не работает, вместо этого он ничего не делает и продолжает всю программу, как будто ничего не произошло.

void hozzaad(ListaElem *s, team *data) { ///adding to the end
        ListaElem *iter = s;
        while (iter->kov=NULL)
        {
            iter = iter->kov;
        }
        ListaElem *uj = new ListaElem(data);
        uj->elozo = iter;
        iter->kov = uj;
    }

    void listaz(ListaElem *s) { //print out all that is in the list
        if (s == NULL) {
            std::cout << "Ures lista" << std::endl;
            return;
        }
        ListaElem *iter = s;
            while (iter!=NULL)
            {
                iter->adat->kiirt(std::cout);
                iter = iter->kov;
        }
    }

void listament(ListaElem *s, const char *a) { //this one creates the file
        std::ofstream file;
        file.open(a);
        ListaElem *iter = s;
        if (file.is_open()) {
            while (iter != NULL) {
                file << iter->adat->Getclub()<< "\n";
                file << iter->adat->Getname() << "\n" << iter->adat->Getmember()<< "\n";
                if (iter->adat->Getclub() == 1) {
                    file << iter->adat->Getsupport() << "\n";
                }
                if (iter->adat->Getclub() == 2) {
                    file << iter->adat->Getpompom() << "\n";
                }
                if (iter->adat->Getclub() == 3) {
                    file << iter->adat->Getname1() << "\n" << iter->adat->Getname2() << "\n";
                }
                iter = iter->kov;
            }
        }
        else
        {
            std::cout << "Nem tudom kinyitni a file-t";
        }
        file.close();
        return;
    };

void test4() {                  // the basic test 
    Handball c("Kezes HC", 21, 50000);
    team adat("", 0);
    ListaElem *egyik = new ListaElem(&adat);
    hozzaad(egyik,&c);
    ListaElem *uj = new ListaElem(&adat);
    listament(egyik, "test.txt"); 
    std::ifstream file;
    file.open("test.txt");
    if (!(file.is_open())) {
        std::cout << "hiba\n";
        return;
    }
    int micsoda;
    while (file >> micsoda);
    {
        if (micsoda == 1) {
            String beolvas("");
            int m;
            int d;
            getline(file, beolvas);
            file >> m;
            file >> d;
            Handball ujh(beolvas, m, d);
            hozzaad(uj, &ujh);
            beolvas = "";
        }
        if (micsoda == 2) {
            String fbeolvas("");
            int fm;
            String e1("");
            String e2("");
            getline(file, fbeolvas);
            file >> fm;
            getline(file, e1);
            getline(file, e2);
            football ujh(fbeolvas, fm, e1, e2);
            hozzaad(uj, &ujh);
        }
        if (micsoda == 3) {
            String bbeolvas("");
            int bm;
            int bd;
            getline(file, bbeolvas);
            file >> bm;
            file >> bd;
            Basketball ujh(bbeolvas, bm, bd);
            hozzaad(uj, &ujh);
        }
    }
    std::cout << "OK" << std::endl;
    listaz(uj);
    file.close();
    std::cout << "OK" << std::endl;
}


test4() expects to go out like:

OK Kezes HC 21 50000 OK

1 Ответ

1 голос
/ 12 мая 2019

Сокращение кода до абсолютно необходимого:

if (micsoda == 1)
{
    Handball ujh;
    hozzaad(uj, &ujh);
} // at this point in code, your object ujh runs out of scope!!!

Когда объект выходит из области видимости, он уничтожается (вы заметите, если добавите какой-либо оператор вывода в деструктор класса)..) и любые указатели на него становятся недействительными;особенно те, что в списке, становятся недействительными (кто-то говорит о висячих указателях - или ссылках, для которых может происходить то же самое).Теперь их использование приводит к неопределенному поведению - что означает, что может произойти что угодно .Если вам не повезло (или вам повезло, в зависимости от точки зрения), ваша программа даже дает сбой.

Имейте в виду, что из-за недостатка важных частей вашего кода я предполагаю, что вы храните только указатели на объекты в вашем классе ListaElem, что весьма вероятно, поскольку хранимые классы полиморфны ...

Однако вам нужны объекты, живущие дольше, чем простопока программа находится в блоке if.Предполагая, что мы нацелены на некоторый реальный сценарий, просто переместить объекты из предложений if невозможно, поскольку нам может потребоваться более одного объекта одного типа.Таким образом, вы будете создавать объекты динамически.Однако тогда вам придется иметь дело с управлением памятью и вопросом владения.Проще всего справиться с управлением памятью с помощью умных указателей.Владение?Что ж, мне кажется разумным предположить, что список является единственным владельцем объектов, поэтому вы можете иметь:

class ListElem
{
    std::unique_ptr<Team> m_data;
public:
    ListElem(std::unique_ptr<Team> data) // accepting a unique_ptr already here indicates
                                         // clearly that the item will grab ownership
        : m_data(std::move(data)) // unique_ptr is only movable, not copiable!
    { }
}

Тогда вы можете изменить свой код выше на:

if (micsoda == 1)
{
    int n, m; // sample data
    hozzaad(uj, std::make_unique<Team>(n, m); // arguments are passed directly to
                                              // the constructor of class Team
}

ОК, вы не можете использовать STL;тогда вы сами напишите свои умные указатели, а также шаблонные функции make_unique и move (как вы уже делали для списков и строк).На cppreference вы можете найти пример реализации, например, для std::make_unique.Не просто скопируйте / вставьте код, но сначала поймите его, а лучше переписайте его с нуля, иначе вы ничего не будете изучать (то же самое относится и к моему коду выше).Или, может быть, вы спросите своего учителя, делает ли он / он исключение в STL для интеллектуальных указателей.

Последний совет: Работа с непрерывной памятью в целом намного быстрее, чем с памятью, потенциально распределенной по всей системной памяти.Таким образом, вы можете рассмотреть возможность повторной реализации std::vector вместо std::list.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...