Использование нескольких классов и связанных списков - PullRequest
0 голосов
/ 24 февраля 2019

В настоящее время я пытаюсь использовать несколько классов (каждый со своим собственным .cpp и заголовочным файлом .h) и связать их, используя основной .cpp. Я хочу создать временный новый указатель видеообъекта, передать аргументы, вставить его в связанный список и удалить временный указатель.После этого мне нужно распечатать каждый отдельный узел списка.

В настоящее время есть 4 файла: main.cpp, vlist.cpp, vlist.h, video.cpp и video.h

Я использую vlist как способ создания связанного списка, который передается в указателе видеообъекта с помощью функции вставки, определенной в файле vlist.cpp. Первая проблема заключается в том, что я не уверен, что делаю это правильно. В настоящее время все, что я делаю, чтобы передать видеообъект в другой класс, это включить video.h вФайл vlist.h.

Вторая проблема заключается в том, что я не могу понять, как правильно получить доступ к отдельным атрибутам видеообъекта в каждом узле, поскольку мои функции получения (определенные в video.h) не будут работать. Кажется, они возвращают адрес, а не значение.Однако всякий раз, когда я пытаюсь это исправить, он говорит мне, что я не могу использовать такую ​​функцию getter.

Моя третья и последняя проблема заключается в том, что в vlist.cpp я не могу передать m_vid при созданииновый узел, но я могу передать m_head просто отлично. Он не скомпилируется, если я не использую myVid (публично объявленный указатель видеообъекта в vlist.h).

Файлы ниже:

main.cpp

#include <iostream>
using namespace std;
#include "vlist.h"
#include "video.h"

int main()
{
    //Create temporary video object pointer using Video * temp = new Video(arguements);
    //Pass in the temp video pointer to the list and insert it with VList function

    string firstLine, secondLine, thirdLine = "";
    float fourthLine = 1.1;
    int fifthLine = 2;

    VList list;

    Video * tempVid = new Video(firstLine, secondLine, thirdLine, fourthLine, fifthLine);
    list.insert(tempVid);
    delete tempVid;
    list.print();
    return 0;
}

video.cpp

#include "video.h"
#include <iostream>

using namespace std;

Video::Video(string title, string URL, string comment, float length, int rating) {
    vidTitle = title;
    vidURL = URL;
    vidComment = comment;
    vidLength = length;
    vidRating = rating;
}

void Video::print(Video *myVid) {
    cout << myVid->getTitle() << endl;
}

video.h

#ifndef VIDEO_H
#define VIDEO_H

#include <string>
#include <iostream>

using namespace std;

class Video
{
    public:
        Video(string title, string URL, string comment, float length, int rating);
        int getRating() {
            return vidRating;
        }
        float getLength() {
            return vidLength;
        }
        string getTitle() {
            return vidTitle;
        }
        string getURL() {
            return vidURL;
        }
        string getComment() {
            return vidComment;
        }
        void print(Video *myVid);
    private:
        string vidTitle, vidURL, vidComment, vidPreference;
        float vidLength;
        int vidRating;
};

#endif

vlist.cpp

#include <iostream>
using namespace std;
#include "vlist.h"


VList::VList() {
    m_head = NULL;
}

VList::~VList() {
    Node *ptr = m_head;
    while (ptr != NULL) {
        Node *temp;

        temp = ptr;
        ptr = ptr->m_next;
        delete temp;
    }
}

void VList::insert(Video *myVid) {
    m_head = new Node(myVid, m_head);
}

void VList::print() {
    Node *ptr = m_head; 
    while (ptr != NULL) {
        cout << ptr->m_vid->getTitle();
        ptr = ptr->m_next;
    }
}

vlist.h

#ifndef VLIST_H
#define VLIST_H
#include "video.h"

class VList
{
    public:
        VList();
        ~VList();
        void insert(Video *myVid);
        void print();
        Video *myVid;

    private:
        class Node
        {
            public:
                Node(Video *myVid, Node *next) {    
                    m_vid = myVid; 
                    m_next = next;
                }
                Video *m_vid;
                Node *m_next;
        };
        Node *m_head;   
};

#endif

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Чтобы ответить на мой собственный вопрос и на любой, кто мог бы увидеть это.Мне просто нужно было немного его изменить, установить указатель временного объекта внутри print и включить функцию get.Уже очень поздно, поэтому я прошу прощения, если есть какие-либо ошибки. Я действительно получал адрес, как я думал.

void VList::print() {
    Node *ptr = m_head; 
    while (ptr != NULL) {
        Video *tempPtr = ptr->m_vid;
        cout << tempPtr->getTitle() << endl;
        ptr = ptr->m_next;
    }
}
0 голосов
/ 24 февраля 2019

Первая проблема в том, что я не уверен, что делаю это правильно.На данный момент все, что я делаю, чтобы передать видеообъект в другой класс, это включить video.h в файл vlist.h.

Нет ,вы делаете это неправильно, в файле main.cpp вы создаете указатель на Video (т.е. Video*) и передаете его в функцию void VList::insert(Video *myVid), а на следующей строке вы удаляете указатель перед печатьюЭто.Помните, что когда вы создаете указатели и передаете их методу, жизненный цикл которого не управляется автоматически, как по волшебству, вы сами должны управлять указателями (что является самой распространенной проблемой для начинающих, я тоже).Таким образом, есть два исправления этой проблемы

Первое исправление

Не удаляется указатель в main, так как он удаляется в деструкторе VList.

#include <iostream>
using namespace std;
#include "vlist.h"
#include "video.h"

int main()
{
    //Create temporary video object pointer using Video * temp = new Video(arguements);
    //Pass in the temp video pointer to the list and insert it with VList function

    string firstLine, secondLine, thirdLine = "";
    float fourthLine = 1.1;
    int fifthLine = 2;

    VList list;

    Video * tempVid = new Video(firstLine, secondLine, thirdLine, fourthLine, fifthLine);
    list.insert(tempVid);
    // delete tempVid; // don't delete this pointer right here, since I've found that you are deleting the pointer in the destructor of VList
    list.print();
    return 0;
}

Второе исправление

Вы можете использовать так называемые умные указатели, так как в C ++ 11 они стандартизированы!См. std::unique_ptr и std::shared_ptr.Они автоматически удаляют указатели и гарантируют отсутствие утечек памяти.

Вторая проблема заключается в том, что я не могу понять, как правильно получить доступ к отдельным атрибутам видеообъекта в каждом узле, потому что мои функции получения (определенные в видео.h) не будет работать.

Ваша вторая проблема связана с первой, поскольку вы удаляете указатель перед его использованием, что приводит к неопределенному поведению, а вывод, который вы можете получить, подобен мусору.не так ли?

Для простоты я бы рекомендовал использовать простые ссылки Video, а не указатели.Передайте их по значению, и все ваши проблемы исчезнут.

...