【问题标题】:How to overload << operator in nested class如何在嵌套类中重载 << 运算符
【发布时间】:2014-10-15 07:05:35
【问题描述】:

我有三个类:ClientDatabaseNode 作为 Database 中的嵌套类。

Node 的数据是指向Client 对象的指针,Client 类有自己的重载&lt;&lt; 运算符。

我需要一个重载的&lt;&lt; 运算符来输出所有链表的数据。 我遇到的问题是无法使用&lt;&lt; 重载运算符遍历所有列表,我能做的最好的事情是使用getData 成员输出头节点的数据,出于某种原因Node::Print不会输出所有列表Client *data

这是Database 类和提到的两个方法&lt;&lt;print()

数据库.h

class Databse
{
    private:
        class Node //node as nested class
        {
            public:
                Node();
                void setNode(Client*&);
                Node* nextNode(Node*&);
                Client getData();
                void print (Node*);
            private:
                Client* data; //holds pointer to Client object
                Node* next; //holds pointer to next node in list
        };

        Node *head; //holds the head node
        int nClients;

    public:
        Databse();
        friend ostream& operator<<(ostream&, const Databse&);
        Node* getHead() const;
        ~Databsey();
};

Databse.cpp相关方法:

ostream& operator<<(ostream& out, const Databse& obj)
{   
    out << endl << "The databse holds" << obj.nClients << " clients:" << endl;
    out << obj.head->getData();        
    obj.head->print(obj.getHead());
    return out;
}

void Database::Node::print (Node* str)
{
    Node* current = str ;
    while (current->next)
    {
        cout << current->data;
        current = current->next;
    }
}

谢谢。

【问题讨论】:

    标签: c++ linked-list operator-overloading


    【解决方案1】:

    只需像添加任何其他类一样添加重载的operator&lt;&lt;,例如:

    class Databse
    {
        private:
            class Node //node as nested class
            {
                public:
                    Node();
                    void setNode(Client*&);
                    Node* nextNode(Node*&);
                    Client getData();
                    friend ostream& operator<<( ostream&, const Node*& pNode );
                private:
                    Client* data; //holds pointer to Client object
                    Node* next; //holds pointer to next node in list
            };
    
            Node *head; //holds the head node
            int nClients;
    
        public:
            Databse();
            friend ostream& operator<<(ostream&, const Databse&);
            friend ostream& operator<<( ostream&, const Node*& pNode );
            Node* getHead() const;
            ~Databsey();
    };
    

    然后实现如下:

    ostream& operator<<( ostream& out, const std::add_lvalue_reference<Databse::Node*>::type pNode )
    {
        Databse::Node* pCurrNode = pNode;
        while( pCurrNode )
        {
            std::cout << pCurrNode->data;
            pCurrNode = pCurrNode->next;
        }
    
        return out;
    }
    

    【讨论】:

    • 这样做会导致两个编译错误:class Database::Node is private
    • @Medvednic 啊,对不起;有两种方法可以解决这个问题,一种是定义内联运算符(即在嵌套类中声明的位置),第二种是在外部类中添加第二行friend ostream&amp; operator&lt;&lt;( ostream&amp;, const Node*&amp; pNode );
    • 此处从 const 到非 const 的无效转换错误:Databse::Node* pCurrNode = pNode;为什么实现没有返回类型?
    【解决方案2】:

    修复接受 ostream 的打印

    ostream& Database::Node::print (ostream& out, Node* str)
    {
      Node* current = str ;
      while (current) //bugfix
      {
        out << current->data;
        current = current->next;
      }
      return out
    }
    

    然后你就可以打电话了

    ostream& operator<<(ostream& out, const Databse& obj)
    {   
      out << endl << "The databse holds" << obj.nClients << " clients:" << endl;
      out << obj.head->getData();        
      obj.head->print(out,obj.getHead());
      return out;
    }
    

    【讨论】:

      【解决方案3】:

      另一种方法。

      1. 保持Database::Node:print() 非常简单——只打印对象上的数据。
      2. ostream&amp; operator&lt;&lt;(ostream&amp; out, const Database&amp; obj) 负责遍历列表中的节点并打印每个节点。

      这是更新后的代码。

      class Database
      {
         private:
            class Node //node as nested class
            {
               public:
                  Node();
                  void setNode(Client*&);
                  Node* nextNode(Node*&);
      
                  // Need this to allow iteration of the list of nodes
                  // of a Database object.
                  Node* nextNode() const
                  {
                     return next;
                  }
                  Client getData();
      
                  // Print the data associated with just one node.
                  void print(ostream& out) const
                  {
                     cout << data;
                  }
      
               private:
                  Client* data; //holds pointer to Client object
                  Node* next; //holds pointer to next node in list
            };
      
            Node *head; //holds the head node
            int nClients;
      
         public:
            Database();
            friend ostream& operator<<(ostream&, const Database&);
            Node* getHead() const;
            ~Database();
      };
      
      ostream& operator<<(ostream& out, const Database& obj)
      {   
          out << endl << "The databse holds" << obj.nClients << " clients:" << endl;
      
          // Iterate over the nodes of the Database object
          // and print each one.
          Database::Node* current = obj.head;
          for ( ; current != NULL; current = current->nextNode() )
          {
             current->print(out);
             // Printing a whitespace between nodes makes the
             // output more readable.
             out << " ";
          }
      
          return out;
      }
      

      【讨论】:

      • 谢谢,它编译没有错误,但只打印对象的地址。
      • cout &lt;&lt; data; 更改为 cout &lt;&lt; *data;
      • 这可能是由于在节点列表中创建错误。
      猜你喜欢
      • 1970-01-01
      • 2013-09-20
      • 2014-10-11
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      相关资源
      最近更新 更多