2012-02-27 149 views
2

我已经从上一学期的一些课程中学习了一些旧的hw任务。 这是打印链接列表对象的给定打印功能。 我不明白为什么重载的操作符需要两个参数,一个是操作系统对象。当我们在main.cpp上打印出实际的链表对象时,我们并不需要通过一个os对象。另外,它为什么返回os?为什么我们不能使用cout 而不是“os < <”?重载运算符<< ostream语法

谢谢!

template <class T> 
void List<T>::print(ostream & os) const 
{ 
    os << "<"; 
    ListNode * curr = head; 
    while (curr != NULL) { 
     os << " " << curr->data; 
     curr = curr->next; 
    } 
    os << " >"; 
} 



// overloaded operator<< 
template <class T> 
ostream & operator<<(ostream & os, const List<T> & list) 
{ 
    list.print(os); 
    return os; 
} 

回答

6

顺便问一下,问题是如何基本的,我会尽量给出一个非常简单的(尽管非常非正式的,不那么迂腐)的答案。

我不明白为什么重载运算符有两个参数 和一个是操作系统对象

操作< <是一个二元运算符。它有一个左侧和一个右侧。当你写:

cout << 123; 

要调用这个操作符有两个操作数(参数):“COUT”在左,一个整数,“123”,在右边。

当我们打印出main.cpp上的实际链表对象时,我们 不需要传递os对象。

您的打印功能是类的成员函数或操作符。这会隐含地推断出,第一个参数粗略地说不需要显式传递,因为你已经有了'this'指针来处理你的列表对象。对于非成员操作符,情况并非如此,因为您没有隐式推导出的“this”对象已经用于左侧操作数。

当你写这样的代码:

my_list.print(cout); 

你可以把它看作实际上传递两个参数,“my_list”和“COUT”。即使你没有明确写出,你可以通过'this'和其成员访问'my_list'。这是不是这样的,如果你写的打印功能作为一个非成员,就像这样:

template <class T> 
void print(const List<T>& my_list, ostream& os); 

这也是与运营商的情况下,这是不是一个成员函数。

此外,它为什么返回os?

返回ostream的基准是什么让我们写这样的语句:

cout << "hello " << "world"; 

首先,我们调用操作< <(COUT,“你好”),然后给了我们另外的ostream参考工作然后让我们继续调用运算符< <(cout,“world”)。例如,如果它返回void,那么它不会允许我们在一个语句中两次调用该操作符,因为我们试图将void作为左边的操作数输出为“world”。

为什么我们不能只用cout而不是“os < <”?

cout基本上实现了ostream接口。所以流,ostringstream,和其他类型的输出流。通过根据需要的基本接口来编写,而不是某个特定的ostream衍生产品,您允许您编写的代码使用stdio流,文件流,流式流等。基本上它使你的代码非常通用和可重用,这是你在实际时应该努力去做的事情。在解决多态性概念时,您将更多地了解这个主题。

+0

“流流”?这是“串流”的错字吗? – 2016-11-01 10:13:57

2

因为它是一个全局非成员函数。使用成员函数版本,第一个参数隐含地是调用对象this。这意味着你的课程总是必须在左边。使用非成员函数,它是一个明确的参数;这样,您可以指定您想要的任何类型,并为无法修改源的类(只要至少一个参数是用户定义的类型)重载操作符。

你使用os的原因是它可以处理文件流和任何东西(任何继承自ostream的东西),而不仅仅是cout

它返回os,以便您可以对返回值执行更多operator<<调用。这使得操作员链接,如w << x << y << z,这是operator<<(operator<<(operator<<(w, x), y), z)相同。如果您返回void或其他东西,则必须在w << x处停止,因为您无法执行任何操作,返回值为void

0

我不明白为什么重载操作符有两个参数,一个是os对象。当我们在main.cpp上打印出实际的链表对象时,我们不需要传递一个os对象。

是的,你做的事:当你说cout << x,你逝去的coutxoperator<<

此外,它为什么返回os?

使cout << x << y成为可能。这被解析为(cout << x) << y,即它将y插入返回值cout << x

为什么我们不能只用cout而不是“os < <”?

因为有时您想输出到另一个流而不是标准输出。

0

当我们打印出main.cpp上的实际链表对象时,我们 不需要传递os对象。

是的,你做了..类似cout << obj;,其中cout是os输出流。

另外,它为什么返回os?为什么我们不能只用cout而不是“os < <”?

这使得链接:cout << obj << " " << obj2;

为什么我们不能只使用,而不是 “OS < <” COUT?

这将硬连线的输出流,所以你不能写入文件或任何其他输出。