【问题标题】:C++: Overloading the << operatorC++:重载 << 运算符
【发布时间】:2013-12-03 07:05:59
【问题描述】:

我有一个非常愚蠢的问题,我就是想不通。我试图在我的“PrioQueue”类中重载

PrioQueue 是我制作的一个模板类,它的工作方式与普通队列类似,但会将它接收到的最高值放在顶部。

PrioQueue<int> intq1(5);
intq1.push(1);
intq1.push(2);
intq1.push(1);
cout << intq1;

2 | 1 | 1 |

这是我的重载运算符

friend std::ostream& operator<<(std::ostream& out, PrioQueue q){
    while(!q.empty()){
        out.write(q.pop()); //This method pops off the top value and returns it
    }
    return out;

}

我希望这是足够的信息,但如果不是。这是我的完整代码:

#include "stdafx.h"
#include <iostream>
#include <ostream>
using namespace std;

template <typename Type>
class PrioQueue
{
private:
Type *bottom_;
Type *top_;
int size_;
public:
PrioQueue(Type size){
    bottom_ = new Type[size];
    top_ = bottom_;
    size_ = size;
}

friend PrioQueue operator+(PrioQueue q1, PrioQueue q2){
    while(!q2.empty()){
        q1.push(q2.pop());
    }
    return q1;
}

friend std::ostream& operator<<(std::ostream& out, PrioQueue q){
    while(!q.empty()){
        out.write(q.pop());
    }
    return out;
}


//Checks to see if the given value is bigger than the bottom character. 
//If so, the bottom and the given value swap places. 
//If not, the value gets placed at the top of the queue
void push(Type t){
    if(*bottom_ < t){
        *top_ = *bottom_;
        *bottom_ = t;
    }else{
        *top_ = t;
    }
    top_++;
}

int num_items() {
    return (top_ - bottom_);
}

Type pop(){
    return *(bottom_++);
}

int full() {
    return (num_items() >= size_);
}

int empty() {
    return (num_items() <= 0);
}

void print(){
    cout << "Queue currently holds " << num_items() << " items: " ;
    for (Type *element=top_-1; element >= bottom_; element--) {
        cout << " " << *element;
    }
    cout << "\n";
}

int getSize(){
    return size_;
}

~PrioQueue(){ // stacks when exiting functions
    bottom_ = 0;
    delete[] bottom_;
}
};

void intExample(){
PrioQueue<int> intq1(5);
intq1.push(1);
intq1.push(2);
intq1.push(1);
cout << intq1;

intq1.print();

PrioQueue<int> intq2(5);
intq2.push(8);
intq2.push(2);
intq2.push(5);
intq2.print();

PrioQueue<int> intq3(10);
intq3 = intq1 + intq2;
intq3.print();

cout << intq3;
}

void charExample(){
PrioQueue<char> charq1(5);
charq1.push('t');
charq1.push('h');
charq1.push('g');
charq1.print();

PrioQueue<char> charq2(5);
charq2.push('i');
charq2.push('q');
charq2.push('k');
charq2.print();

PrioQueue<char> charq3(10);
charq3 = charq1 + charq2;
charq3.print();
}

int main(){
intExample();
charExample();

return 0;
}

【问题讨论】:

  • 作为建议,您可能需要重新考虑在输出时删除所有内容的设计(+ 运算符也是如此)。
  • @crashmstr 我只是在输入关于此的评论。这不是问题,因为对象是按值传递的。但是,您可能希望提供一个显式的副本构造函数,以确保您传入的副本不会与原始副本秘密共享某些数据结构。
  • @CompuChip 是的,但在我看来,传递const &amp; 然后以非破坏性方式迭代更有意义。

标签: c++ templates operator-overloading priority-queue ostream


【解决方案1】:

这可行:

friend std::ostream& operator<<(std::ostream& out, PrioQueue q){
  while(!q.empty()){
    out << q.pop() << "|";
  }
  return out << "\n"; // if you want a newline, otherwise just "return out;"
}

编辑请注意,要使其正常工作,您必须将队列修改为可复制。您需要添加一个复制构造函数和一个赋值运算符(请参阅the rule of three)或使用可复制和可分配的类型来存储您的数据(请参阅std::vectorstd::deque 或容器适配器std::priority_queue,如果不是这样的话练习)。

【讨论】:

  • 如果队列是(正确)可复制的,那就没问题了。虽然,作为朋友,直接访问数据而不需要复制它可能更有意义。
  • @MikeSeymour 谢谢。我错误地假设队列是可复制的,并且副本是故意的,因为打印队列可能不应该清空它。但现在我看到有问题。我对此添加了一些内容。
【解决方案2】:

问题在于out.write() 需要const char*size。首先,您的 Type 不会隐式转换为 const char* ,而且您缺少一个参数。

使用 q.pop() 将为您解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2016-04-08
    • 2012-06-02
    • 2014-01-14
    • 2013-03-23
    • 2013-06-07
    相关资源
    最近更新 更多