C ++ - 模板,链接列表和类

时间:2018-04-19 16:44:46

标签: c++ linked-list

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

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

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

构建开始:项目:Project25,配置:调试Win32 ------ 1 GT; PatientTest.cpp 1> c:\ users \ user \ documents \ visual studio 2013 \ projects \ project25 \ project25 \ patienttest.cpp(75):错误C2955:'PatientType':使用类模板需要模板参数列表

1> c:\ users \ user \ documents \ visual studio 2013 \ projects \ project25 \ project25 \ patienttest.cpp(17):见'PatientType'声明

1> c:\ users \ user \ documents \ visual studio 2013 \ projects \ project25 \ project25 \ patienttest.cpp(75):错误C2133:'plist':未知大小

1> c:\ users \ user \ documents \ visual studio 2013 \ projects \ project25 \ project25 \ 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'的模板参数,期望是真实类型

3 个答案:

答案 0 :(得分:1)

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

PatientType<int> plist;

答案 1 :(得分:0)

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

中的类型,那么您的程序会更好用
Node<PatientType>* head;

所以你得到了

Node<PatientType>* head;

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

答案 2 :(得分:0)

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

我的第一个想法是从PatientType中移除模板,但这并没有解决导致您达到这一点的设计错误:您已将患者与列表混为一谈。您可以保持对象责任的范围越有限,从概念上(患者是患者,而不是患者列表)以及维护和调试就越好。这涉及封装和耦合的基本的面向对象编程概念,并且可能至少有两个你期望通过这个任务学习和演示的东西。

如果这不是作业,请站在巨人的肩膀上并使用std::list而不是滚动自己的链接列表。

继续假设这确实是用于教育目的的分配,从PatientType中删除所有类似列表的行为,并创建第三个类,即链接列表管理器。

在此替代方案PatientType除了管理单个患者之外什么都不做,Node除了允许患者联系在一起之外什么都不做,LinkedList除了链接患者的节点之外什么都不做。每个结构都尽可能简单和无知。 PatientTypeNodeLinkedList一无所知。通过模板的魔力,NodeLinkedListPatientType一无所知。 NodeLinkedList一无所知,但LinkedList知道Node的所有内容,因为LinkedLists的工作要知道Nodetemplate <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

Node失去了Node的所有知识以及int main() { LinkedList<PatientType> list; list.insert(PatientType(/*parameters*/)) } 的链接。

dataframe %>%
  select(Sex, ChemistryPc, MathsPc, PhysicsPc, TotalRank) %>%
  group_by(TotalRank) %>%
  summarise_at(vars(-Sex), funs(mean(., na.rm=TRUE))) %>%
  gather(key = 'Class', value = 'ValuePc', -TotalRank)

现在,您可以单独处理所有测试它们的部件。什么都不放,直到你知道它分开正常工作。错误会增加查找和解决任何一个错误的难度,因此,您在任何时候遇到的错误越少越好。