使用多个类和链表

Posted

技术标签:

【中文标题】使用多个类和链表【英文标题】:Using multiple classes and linked lists 【发布时间】:2019-02-24 05:16:17 【问题描述】:

目前我正在尝试使用多个类(每个类都有自己的 .cpp 和头 .h 文件)并使用主 .cpp 链接它们。 我想做一个临时的新视频对象指针,传入参数,插入到链表中,然后删除临时指针。之后,我需要打印列表中的每个单独节点。

目前有4个文件:main.cpp、vlist.cpp、vlist.h、video.cpp、video.h

我使用 vlist 作为一种方法来构造一个链表,该链表通过 vlist.cpp 文件中定义的插入函数传入视频对象指针中。 第一个问题是我不确定我是否正确地这样做了。 目前,为了能够在另一个类中传递视频对象,我所做的只是将 video.h 包含在vlist.h 文件。

第二个问题是我无法弄清楚如何正确访问每个节点中的各个视频对象属性,因为我的 getter 函数(在 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(arguments);
    //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;

视频.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;

视频.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

【问题讨论】:

【参考方案1】:

第一个问题是我不确定我这样做是否正确。 目前,我所做的一切都是为了能够传递一个视频对象 另一个类是在 vlist.h 文件中包含 video.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(arguments);
    //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_ptrstd::shared_ptr。它们会自动删除指针并保证没有内存泄漏。

第二个问题是我不知道如何正确访问 每个节点中的单个视频对象属性,因为我的吸气剂 函数(在 video.h 中定义)将不起作用。

您的第二个问题与第一个问题有关,因为您在使用它之前删除了指针,这会导致未定义的行为,并且您可能得到的输出就像垃圾一样。不是吗?

为了简单起见,我建议使用简单的Video 引用而不是指针。按值传递它们,您的所有问题都会烟消云散。

【讨论】:

我明白,我也有一个 vlist 类的解构器,但我不确定我是否正确使用它。到目前为止,我的其他问题有什么解决办法吗?我不确定我的 getter 函数是否会以这种方式工作。我需要用 getter 函数改变什么吗?我将如何使用视频参考? @Jaskal 它应该可以工作,因为之前你是从一个已删除的指针调用这些函数,这是未定义的行为(给出垃圾输出),现在你是从一个存在的有效指针调用的。【参考方案2】:

回答我自己的问题以及任何可能看到此问题的人的问题。我只需要稍微改变它并在 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;
    

【讨论】:

以上是关于使用多个类和链表的主要内容,如果未能解决你的问题,请参考以下文章

六大区别 (重载与重写顺序表和链表Comparable和Comparator抽象类和接口super和thisArrayList和LinkedList)

数组和链表的区别ArrayList和LinkedList的区别使用LinkedList模拟栈和队列

使用邻接表在 C++ 中实现 DFS(使用 <vector> 和链表)

二叉树,使用指针和链表实现

Java 数组和链表的区别以及使用场景

优先级队列(从头开始)和链表