C++ C++;课程及;链表:添加&;清点物品

C++ C++;课程及;链表:添加&;清点物品,c++,linked-list,C++,Linked List,我需要制作一个有类的链表。每个列表将存储两个值:URI和IP。在完成所有添加之后,我需要能够计算链表中的项目总数。我已经尝试了下面的代码,但是没有编译。我们不允许使用std::list。有什么建议吗 #include <iostream> #include <cstdlib> #include <string> using namespace std; class ip_uri_store { protected: string ip;

我需要制作一个有类的链表。每个列表将存储两个值:URI和IP。在完成所有添加之后,我需要能够计算链表中的项目总数。我已经尝试了下面的代码,但是没有编译。我们不允许使用std::list。有什么建议吗

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

class ip_uri_store {
  protected:
    string ip;
    string uri;
    ip_uri_store *next;

  public:
     ip_uri_store(string huri, string hip);
    void additem(string auri, string aip);
    void deleteitem(string duri);
    void findbyuri(string furi);
    void findbyip(string fip);
    int totalitems();
};

ip_uri_store *head = NULL;
ip_uri_store *curr = NULL;

void ip_uri_store::additem(string auri, string aip)
{
    curr = head;
    while (curr->next != NULL) {
 curr = curr->next;
    }

    curr->uri = auri;
    curr->next = new ip_uri_store;
    curr->ip = aip;
    curr->next = new ip_uri_store;
    curr = curr->next;
    curr = head;
}

int ip_uri_store::totalitems()
{
    int i = 0;

    curr = head;

    while (curr->next != NULL) {
 i += 1;
 curr = curr->next;
    }

    return i;
}

int main(int argc, char *argv[])
{
    if (argc == 1) {
 cout << "123456, 123456@student.rmit.edu.au, Gordon Brown" << endl;
 return (0);
    }

    head = new ip_uri_store;
    curr = head;
    int i;


    for (i = 1; i < argc; i++) {

 if (argv[i][0] == 'A') //add item
 {
     ip_uri_store.additem(argv[i + 1], argv[i + 2]);
     i += 2;
 }

 else if (argv[i][0] == 'N') //print total tiems
 {
     cout << ip_uri_store.totalitems() << endl;
 }

 else {
     cout << "command error\n";
     return 0;
 }
    }
    return (0);
}
#包括
#包括
#包括
使用名称空间std;
类ip_uri_存储{
受保护的:
字符串ip;
字符串uri;
ip_uri_store*下一步;
公众:
ip_uri_商店(字符串huri,字符串hip);
无效附加项(字符串auri、字符串aip);
无效删除项(字符串duri);
void findbyuri(字符串furi);
void findbyip(字符串fip);
int totalitems();
};
ip_uri_store*head=NULL;
ip_uri_store*curr=NULL;
void ip_uri_store::additem(字符串auri,字符串aip)
{
curr=头;
while(当前->下一步!=NULL){
当前=当前->下一步;
}
curr->uri=auri;
curr->next=新的ip\u uri\u存储;
curr->ip=aip;
curr->next=新的ip\u uri\u存储;
当前=当前->下一步;
curr=头;
}
int ip_uri_存储::totalitems()
{
int i=0;
curr=头;
while(当前->下一步!=NULL){
i+=1;
当前=当前->下一步;
}
返回i;
}
int main(int argc,char*argv[])
{
如果(argc==1){

cout您需要向
ip\u uri\u存储
类的构造函数提供两个参数:

// The constructor call needs two arguments
curr->next = new ip_uri_store(huri, hip);
不能对类本身调用实例方法:

// Invalid, totalitems() is valid only on instances of ip_uri_store. 
cout << ip_uri_store.totalitems() << endl;
函数
additem
可以创建
ip\u uri\u store\u节点的新实例,如下所示:

curr->next = new ip_uri_store_node(auri, aip);

其余的取决于您。

您需要向
ip\u uri\u存储
类的构造函数提供两个参数:

// The constructor call needs two arguments
curr->next = new ip_uri_store(huri, hip);
不能对类本身调用实例方法:

// Invalid, totalitems() is valid only on instances of ip_uri_store. 
cout << ip_uri_store.totalitems() << endl;
函数
additem
可以创建
ip\u uri\u store\u节点的新实例,如下所示:

curr->next = new ip_uri_store_node(auri, aip);

其余的由您决定。

您的
ip\u uri\u store::additem()
非常混乱。在其中,您可以在为
curr
对象分配新值之前更改该对象:

curr->uri = auri;
curr->next = new ip_uri_store;
这样做,您就可以更改列表中的最后一项,而不是将
auri
分配给以后添加的新项。(有趣的是,您通过
ip
获得了正确的顺序)


我喜欢给出代码名的想法,这样你就可以阅读它们的功能。函数就是这样做的。例如,我会计算出找到最后一个列表节点的代码

ip_uri_store *find_last_node(ip_uri_store *curr)
{
    while (curr->next != NULL) {
        curr = curr->next;
    }
    return curr;
}
并从
ip\u uri\u store::additem()调用它:

现在在
curr->next

    // ...
    curr->next = new ip_uri_store(auri,aip);
}

您的
ip\u uri\u store::totalitems()
返回一个
int
。为什么?您是否期望对象计数为负数?最好返回一个无符号类型


你应该考虑删除列表节点时发生的事情。如果它仍然指向一个<代码>下< /Cord>对象,那么指针就不会存储在其他任何地方,因此对象(以及它指向的对象)泄漏。处理这个问题的一种方法是编写一个析构函数,用于<代码> IpIururiSturt。(如果要删除节点而不让其删除自己的尾部,可以首先将

NULL
分配给其
next
指针。)

此外,根据,您需要考虑复制列表节点。在第一次尝试中不容易做到这一点,因此您可能只想禁止它:

class ip_uri_store {
  private:
    ip_uri_store(const ip_uri_store&); // not implemented
    ip_uri_store& operator=(const ip_uri_store&); // not implemented
  // ...

不要使用全局变量,而是将它们放入类中。这样可以有多个列表。将
ip\u uri\u store
重命名为
ip\u uri\u store\u impl
并将其放入新的
ip\u uri\u store
类中:

class ip_uri_store {
  private:
    class ip_uri_store_impl { /* ... */ };
    ip_uri_store_impl* head;
};
由于此类管理动态分配的对象,因此需要考虑销毁和复制此类对象


包装类应该有公共方法,这些方法在需要时调用
ip\u uri\u store\u impl
的方法。像
totalitems()
这样的函数操作整个列表(而不是节点),可能应该在包装类中实现。

您的
ip\u uri\u store::additem()
非常混乱。在它中,您在为对象指定新值之前更改
curr
对象:

curr->uri = auri;
curr->next = new ip_uri_store;
这样做,您就可以更改列表中的最后一项,而不是将
auri
分配给以后添加的新项。(有趣的是,您通过
ip
获得了正确的顺序)


我喜欢给出代码名的想法,这样你就可以阅读它们的功能。函数就是这样做的。例如,我会计算出找到最后一个列表节点的代码

ip_uri_store *find_last_node(ip_uri_store *curr)
{
    while (curr->next != NULL) {
        curr = curr->next;
    }
    return curr;
}
并从
ip\u uri\u store::additem()调用它:

现在在
curr->next

    // ...
    curr->next = new ip_uri_store(auri,aip);
}

您的
ip\u uri\u store::totalitems()
返回一个
int
。为什么?您是否期望对象计数为负数?最好返回一个无符号类型


你应该考虑删除列表节点时发生的事情。如果它仍然指向一个<代码>下< /Cord>对象,那么指针就不会存储在其他任何地方,因此对象(以及它指向的对象)泄漏。处理这个问题的一种方法是编写一个析构函数,用于<代码> IpIururiSturt。(如果要删除节点而不让其删除自己的尾部,可以首先将

NULL
分配给其
next
指针。)

此外,根据,您需要考虑复制列表节点。在第一次尝试中不容易做到这一点,因此您可能只想禁止它:

class ip_uri_store {
  private:
    ip_uri_store(const ip_uri_store&); // not implemented
    ip_uri_store& operator=(const ip_uri_store&); // not implemented
  // ...

不要使用全局变量,而是将它们放入类中。这样可以有多个列表。将
ip\u uri\u store
重命名为
ip\u uri\u store\u impl
并将其放入新的
ip\u uri\u store
类中:

class ip_uri_store {
  private:
    class ip_uri_store_impl { /* ... */ };
    ip_uri_store_impl* head;
};
由于此类管理动态分配的对象,因此需要考虑销毁和复制此类对象

包装器类应该