【问题标题】:Overloading << Operator to Print Vector Data Member重载 << 运算符以打印向量数据成员
【发布时间】:2019-03-12 14:47:51
【问题描述】:

我创建了一个带有私有向量的类,它使用 std::string 作为其数据类型。

#pragma once
#include <string>
#include <vector>
#include <iostream>

class Pokemon {
public:
//Constructor - leaving it here for reference
Pokemon(std::string name, int LVL, int HP, int ATK, int DEF, int SPATK, int SPDEF, int SPD, 
std::vector<std::string>moves, std::vector<int>PP);
//Member Functions
std::vector<std::string> getMoves();
private:
std::vector<std::string>moves;
};   

为了从该向量中检索信息,我创建了一个名为 getMoves() 的公共类函数,它应该返回该向量中的所有信息。这是我在 .cpp 文件中编写的函数定义。

std::vector<std::string> Pokemon::getMoves() {
    return moves;
}

在尝试使用 std::cout 打印具有这些移动的向量并收到“与运算符不匹配”错误后,我意识到我必须重载

我有几个关于如何重载

  1. 我不确定在哪里声明重载运算符。我在上课之前声明它吗?在我的课堂上作为公共朋友功能?在不同的头文件中?在我的主要功能中?
  2. 我应该重载打印什么类型?我相信它与我的类是同一类型,因为 getMoves() 函数属于 Pokemon 类,但我不确定是那个还是std::vector&lt;std::string&gt;
    1. 如何在我的主函数中使用这个重载的运算符?就像普通的 std::cout 一样?

感谢您对这些问题的任何帮助,谢谢!

【问题讨论】:

  • 您可以将vector&lt;std::string&gt; 放在反引号中以避开&lt;&gt;
  • @BennoStraub 指出,谢谢!
  • 您可以为vector 和重载运算符创建包装类
  • 你的问题太宽泛了。请一题一题。无论如何,这应该有助于澄清其中一些:stackoverflow.com/questions/4421706/…
  • @user463035818 我很欣赏这个主题的链接,谢谢!很抱歉在一个问题中问了几个问题,我以后会记住的

标签: c++ class c++11 vector operator-overloading


【解决方案1】:

以下示例将为每个向量重载&lt;&lt; 运算符。如果您想为特定向量指定输出,请创建一个包装器结构或类。

#include <iostream> 
#include <vector>

using namespace std; 

template <typename T> 
ostream& operator<<(ostream& os, const vector<T>& v) 
{ 
    os << "[";
    for (int i = 0; i < v.size(); ++i) { 
        os << v[i]; 
        if (i != v.size() - 1) 
            os << ", "; 
    }
    os << "]\n";
    return os; 
}

现在当你想像这样打印矢量时:

int main() {
    vector<int> a = {0, 1, 2};
    cout << a << endl;
}

它将打印以下结果:[0, 1, 2]

【讨论】:

  • 非常感谢您的帮助!我没有考虑过这个模板会有多大用处。这比重载单个类型更有效吧?
  • 我建议您创建自己的包装类并专门重载&lt;&lt; 运算符。这总是比重载整个标准 vector 类更好的方法。
【解决方案2】:
#include <iostream>
#include <vector>
#include <map>

// Helper Function to Print Test Containers (Vector and Map)
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& p) {
    out << "[" << p.first << ", " << p.second << "]";
    return out;
} 

template <template <typename, typename...> class ContainerType, typename 
ValueType, typename... Args>
void print_container(const ContainerType<ValueType, Args...>& c) {
    for (const auto& v : c) {
        std::cout << v << ' ';
    }
    std::cout << '\n';
}

正如 NutCracker 所提到的,operator &lt;&lt; 重载几乎是所有类型容器中的最佳朋友。除了他的好回答之外,这里还有一个模板化分辨率的扩展版本,用于打印所有类型的 STL 容器。

除了向量之外,还可以对成对类型的容器进行重载。举个例子。 ValueType -&gt; First or only Element in container templateArgs... variadic template as rest of the elements in container(第二个或更多元素) 对于pair &lt;T,U&gt; basic map-unordered_map,您只有overload 的第一个和第二个元素 您可以将此技术应用于几乎所有容器类型。 如果您只想打印每个口袋妖怪功能而不调用任何附加函数pokemon::getMoves() 您也可以overload &lt;&lt; for pokemon class 最好只打印 1 个口袋妖怪等。

friend 授予私人和公共成员访问权限

friend ostream& operator<< (ostream& os, const Pokemon& pokemonobj) {
    os << print_container(pokemonobj.getMoves());
    return os;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多