C++ - 模板、链表和类

C++ - Templates, Linked Lists and Classes

本文关键字:链表 模板 C++      更新时间:2023-10-16

我必须编写一个使用三种数据结构(其中一个是链表)的C++程序。该程序最终必须从CSV中读取数据,允许用户向CSV添加信息,并允许人们在CSV中搜索数据。

我正在尝试创建一个患者类,该类将获取CSV文件中的数据,将每行数据存储到患者对象中,然后通过链表链接这些对象。

一切似乎都很好,但是当我构建时,我收到以下错误消息:

生成已开始:项目:项目25,配置:调试 Win32 ------ 1>患者测试.cpp 1>c:\用户\用户\文档\Visual Studio 2013\项目\项目25\项目25\耐心测试.cpp(75):错误 C2955:"患者类型":使用类模板需要模板参数列表

1>c:\users\user\documents\Visual Studio 2013\projects\project25\project25\patienttest.cpp(17):参见"PatientType"的声明

1>c:\用户\用户\文档\Visual Studio 2013\项目\项目25\项目25\耐心测试.cpp(75): 错误 C2133:"plist":未知大小

1>c:\用户\用户\文档\Visual Studio 2013\项目\项目25\项目25\PatientTest.cpp(75):错误 C2512:"PatientType":没有可用的适当默认构造函数

==========构建:0 成功,1 失败,0 最新,0 跳过 ====

======这是我到目前为止的代码:

#include <iostream>
#include<iostream>
#include<string>
#include<fstream>
#include <cassert> 
using namespace std;
template <class Type>
struct Node
{
Type info;
Node<Type> *next;
};
template <class Type>
class PatientType
{
public:
//Constructors
PatientType();
PatientType(string patientSSN, string patientFName, string patientLName, string patientEmail, string patientNumber);
//Accessors
string getPSSN();
string getPFName();
string getPLName();
string getPEmail();
string getPNumber();
//Mutators
void setPSSN(string newPSSN);
void setPFName(string newPFName);
void setPLName(string newPLName);
void setPEmail(string newPEmail);
void setPNumber(string newPNumber);
void print();
void loadList(Node<Type>);
private:
int length;
Node<Type>* head;
string pSSN;
string pFName;
string pLName;
string pEmail;
string pNumber;
};
template <class Type>
PatientType<Type>::PatientType()
{
pSSN = "SSN";
pFName = "First Name";
pLName = "Last Name";
pEmail = "Email";
pNumber = "Phone Number";
}
template <class Type>
PatientType<Type>::PatientType(string patientSSN, string patientFName, string patientLName, string patientEmail, string patientNumber)
{
pSSN = patientSSN;
pFName = patientFName;
pLName = patientLName;
pEmail = patientEmail;
pNumber = patientNumber;
}

int main()
{
PatientType plist;
system("pause");
return 0;
}

**更新 - 我尝试做PatientType<PatientType> pList;出现以下错误: "PatientType":非专用类模板不能用作模板参数"Type"的模板参数,预期为实际类型

实例化模板时,您需要提供模板类型,例如

PatientType<int> plist;

查看问题中的代码如何使用PatientType,似乎PatientType根本不需要模板。它不使用任何模板化行为,除了Node<Type> * head;和添加更多Node<Type>的函数调用。

我的第一个想法是从PatientType中删除模板,但这并不能解决使您走到这一步的设计错误:您将患者与列表混为一谈。保留对象职责的范围越有限,在概念上(患者是患者,而不是患者列表)以及维护和调试方面就越好。这涉及到封装和耦合的基本面向对象编程概念,并且可能至少是您希望通过此作业学习和演示的两件事。

如果这不是一项任务,请站在巨人的肩膀上并使用std::list而不是滚动自己的链表。

继续假设这确实是出于教育目的的作业,从PatientType中删除所有类似列表的行为,并制作第三类,即链表管理器。

在这种替代PatientType除了管理单个患者之外什么都不做,Node除了允许患者链接在一起之外什么也不做,LinkedList除了链接患者的节点之外什么都不做。每个结构都尽可能简单和无知。PatientTypeNodes和LinkedLists一无所知。通过模板的魔力,NodeLinkedListPatientType一无所知。NodeLinkedList一无所知,但LinkedListNode了如指掌,因为了解NodeLinkedLists的工作。有些耦合是不可避免的。

template <class Type>
struct Node
{
Type info;
Node<Type> *next;
};

节点保持不变。

template <class Type>
class LinkedList
{
Node<Type> *head;
public:
LinkedList();
LinkedList(const LinkedList&); // required by the Rule of Three
~LinkedList();
LinkedList& operator=(const LinkedList&); // required by the Rule of Three
void insert(const Type&);
void remove(const Type&);
void print(std::ostream &);
// other functions as required
};

请注意,对于这个简单示例,LinkedList的用户需要对Node一无所知。他们只知道他们有一个LinkedList,它为他们保存东西。另请注意,我省略了如何在列表中查找某些内容。这很棘手,但它需要等到您可以在列表中添加和删除内容并成功打印它之后。

建议:从int列表开始,并确保在继续处理患者列表之前,您可以对患者执行所有需要int操作,因为使用简单的东西进行测试要容易得多。

在添加任何不是立即必要的难度之前,您将不得不对列表进行大量测试。链表是一项除草作业,需要您了解许多不同的材料才能执行。实际上,没有人在前几次自己工作就能做到正确。

绘制图片以帮助可视化列表。

class PatientType
{
public:
// public stuff that has no bearing on this example
// void loadList(Node<PatientType>); eliminated
private:
// Node<PatientType>* head; eliminated
// private stuff that has no bearing on this example
};

PatientType失去了所有关于NodeNodes链接的知识。

int main()
{
LinkedList<PatientType> list;
list.insert(PatientType(/*parameters*/))
}

现在,您可以独立处理所有单独测试它们的部件。在你知道它单独正常工作之前,什么都不放在一起。Bug 会放大查找和解决任何一个 bug 的难度,因此您在任何时候遇到的 bug 越少越好。

如果PatientType不是模板并且您直接在

Node<PatientType>* head;

所以你得到

Node<PatientType>* head;

由于这是C++您可以使用std::list而不是玩指针游戏,除非这是任务的一部分。