【问题标题】:Operator Overload << in Linked List运算符重载 << 在链表中
【发布时间】:2010-12-06 04:54:29
【问题描述】:

如何使operator &lt;&lt; 过载。 重载运算符的目的是: cout &lt;&lt; ptr-&gt;info 不接收内存地址,但显示该节点信息部分的制造商年份和型号。

例子:

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

在节点的每个信息部分都会有一个这样的结构:

struct Car {
    string maker;
    string year;
    string model;
}

到目前为止,我有这个,但它似乎不起作用:

friend ostream &operator << ( ostream &output, Node<DataType> &rlist ) { //Overloaded <<
    output << rlist->info.make << endl;
    output << rlist->info.year << endl;
    output << rlist->info.price << endl; 

    return output;
}  

当我用 g++ 编译时,我得到了这个错误:

LinkedList.cpp: In member function ‘void LinkedList<DataType>::EscribaUltimo() [with DataType = CarType]’:
main.cpp:37:   instantiated from here
LinkedList.cpp:15: error: no match for ‘operator<<’ in ‘std::cout << ptr->Node<CarType>::info’

【问题讨论】:

  • @Jacob,至少我们决斗编辑到相同的标签:)
  • 这件事将在大约 2 次编辑后最终成为社区 wiki...
  • @GMan:我打算进行运算符重载:)
  • 我想没有更多的编辑。为什么这么多人编辑了这么多次...谁知道呢。
  • 哈哈,同意。我的光标不会再次使retag 按钮变暗!

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


【解决方案1】:

虽然我有点困惑,因为您缺少实际的主要代码。我假设你有一个节点,从遍历链接,现在想要打印它:

#include <iostream>
#include <string>

using namespace std; // not recommended, but useful
                     // in snippets

// T is usually used, but this is of course up to you
template <class T> 
struct Node
{
    typedef T value_type; // a usual typedef

    value_type info;
    Node<value_type> *next;
};

struct Car
{
    string maker;
    string year;
    string model;
}; // you had a missing ;, probably copy-paste error

// this creates a node. normally you'd want this to be
// wrapped into a list class (more on this later)
template <typename T>
Node<T> *createNode(const T& info = T())
{
    // allocate node
    Node<T> *result = new Node<T>;
    result->info = info;
    result->next = 0; // no next

    return result; // returning a pointer means
                   // whoever gets this is
                   // responsible for deleting it!
}

// this is the output function for a node
template <typename T>
std::ostream& operator<<(std::ostream& sink, const Node<T>& node)
{
    // note that we cannot assume what node contains!
    // rather, stream the info attached to the node
    // to the ostream:
    sink << node.info;

    return sink;
}

// this is the output function for a car
std::ostream& operator<<(std::ostream& sink, const Car& car)
{
    // print out car info
    sink << "Make: " << car.maker <<
            "\nYear: " << car.year <<
            "\nModel: " << car.model << std::endl;

    return sink;
}

int main(void)
{
    // a car list
    typedef Node<Car> CarList;

    // a couple cars
    Car car1 = {"Dodge", "2001", "Stratus"};
    Car car2 = {"GMan's Awesome Car Company", "The future", "The best"};

    CarList *head = createNode(car1); // create the first node
    head->next = createNode(car2);

    // now traverse the list
    CarList *iter = head;
    for (; iter != 0; iter = iter->next)
    {
        // output, dereference iterator to get the actual node
        std::cout << "Car: " << *iter << std::endl;
    }

    // dont forget to delete!
    iter = head;
    while (iter)
    {
        // store next
        CarList *next = iter->next;

        // delete and move on
        delete iter;
        iter = next;
    }
}

现在,如果您不必创建自己的链表,请改用标准链表,它会极大地简化您的任务:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
#include <string>

using namespace std;

struct Car
{
    string maker;
    string year;
    string model;
};


// this is the output function for a car
std::ostream& operator<<(std::ostream& sink, const Car& car)
{
    // print out car info
    sink << "Make: " << car.maker <<
            "\nYear: " << car.year <<
            "\nModel: " << car.model << std::endl;

    return sink;
}

int main(void)
{
    // a car list
    typedef std::list<Car> CarList;

    // a couple cars
    Car car1 = {"Dodge", "2001", "Stratus"};
    Car car2 = {"GMan's Awesome Car Company", "The future", "The best"};

    CarList cars;
    cars.push_back(car1);
    cars.push_back(car2);

    // now traverse the list (copy to ostream)
    std::copy(cars.begin(), cars.end(),
             std::ostream_iterator<Car>(std::cout,"\n"));

    // delete done automatically in destructor
}

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    只是为了确保,你有

    template<class DataType>
    

    在运算符定义之前,对吧?如果我这样做,它对我有用。错误消息显示代码中的行号,但它在粘贴定义中的什么位置?看完了,我觉得问题不在于

    Node<DataType> myNode;
    output << myNode 
    

    但有

    output << myNode.info
    

    没有为其定义运算符

    编辑:根据您的评论,听起来您想为汽车定义

    ostream& operator<< (ostream& output, Car& car) {
      output << car.foo << end;
      output << car.bar << end;
      return output;
    }
    
    template <class DataType>
    ostream& operator<< (ostream& output, Node<DataType>& node ) {
      output << node.info << end;
      return output;
    }
    

    基本上,这意味着当您专门化您的 Node 类型并希望在其上使用

    【讨论】:

    • 我不知道如何为 myNode.info 定义运算符
    • 鉴于 Naveen 对 Car 访问错误的(正确)评论,加上给定的运算符充其量是 Car 模板的专门化,我发现它对您有用,这让我感到惊讶。你真的得到了输出,还是仅仅编译了?
    • 马丁,有什么工作要做?甚至没有 main 函数。我的意思是我拿了 Loki 提供的代码,得到了类似的东西。抱歉不准确。
    • 我仍然不清楚你要工作的是什么(特别是如果它不是你的 /untested/ 代码)。但是,它必须在更多方面偏离原始代码,而不仅仅是将缺少的模板声明添加到操作符。
    【解决方案3】:

    您需要两个运算符:一个用于 Node(或 Node*),一个用于 Car:

    ostream &operator << ( ostream &output, Car &car ) {
        output << car.maker << endl;
        output << car.year << endl;
        output << car.model << endl; 
        return output;
    }
    
    template<class DataType>
    ostream &operator << ( ostream &output, Node<DataType> *rlist ) {
        output << rlist->info;
        return output;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 2013-03-05
      相关资源
      最近更新 更多