【问题标题】:C++ Trouble with overloading >>C++重载问题>>
【发布时间】:2014-09-22 20:29:12
【问题描述】:

我正在开发一个程序,并且已经调试了很多我在其中做错的地方。我只有一个错误,并且在堆栈和其他论坛上阅读过有关类似问题的信息。但是尝试一遍又一遍地重做,没有任何积极的结果。

头代码中显示的错误是:

binary'>>' 未找到采用'overloaded-function' 类型右侧操作数的运算符(或没有可接受的转换)

月.h

#ifndef MONTH_H
#define MONTH_H

#include <iostream>
#include <string>

using namespace std;

class Month{
private:
        static string name;
        static int monthNumber;
public:
        //Default Constructor
        Month(){
        setName("January");
        setNumber(1);
        }
        //Input of month only constructor and assigning month number from input of name
        Month(string n){
                name = n;
                setName(n);
                if(name == "January" || name == "january"){
                        setNumber(1);
                }
                else if(name == "February" || name == "february"){
                        setNumber(2);
                }
                else if(name == "March" || name == "march"){
                        setNumber(3);
                }
                else if(name == "April" || name == "april"){
                        setNumber(4);
                }
                else if(name == "May" || name == "may"){
                        setNumber(5);
                }
                else if(name == "June" || name == "june"){
                        setNumber(6);
                }
                else if(name == "July" || name == "july"){
                        setNumber(7);
                }
                else if(name == "August" || name == "august"){
                        setNumber(8);
                }
                else if(name == "September" || name == "september"){
                        setNumber(9);
                }
                else if(name == "October" || name == "october"){
                        setNumber(10);
                }
                else if(name == "November" || name == "november"){
                        setNumber(11);
                }
                else if(name == "December" || name == "december"){
                        setNumber(12);
                }
        }
        //Input of month number only and assigning month name to that number
        Month(int n){  
                setNumber(n);
        }
        Month(int n, string m){
            monthNumber = n;
            name = m;
        }
        //Set the name of the month
        void setName(string n){
                name = n;
        }
        //Set the monthes number (and name for increment and decrement)
        void setNumber(int n){
                monthNumber = n;
                switch(monthNumber){
                case 1:
                        setName("January");
                        break;
                case 2:
                        setName("February");
                        break;
                case 3:
                        setName("March");
                        break;
                case 4:
                        setName("April");
                        break;
                case 5:
                        setName("May");
                        break;
                case 6:
                        setName("June");
                        break;
                case 7:
                        setName("July");
                        break;
                case 8:
                        setName("August");
                        break;
                case 9:
                        setName("September");
                        break;
                case 10:
                        setName("October");
                        break;
                case 11:
                        setName("November");
                        break;
                case 12:
                        setName("December");
                        break;
        }
    }
        //Return the name of the month
        string getName(){
                return name;
        }
        //Return the month number
        int getNumber(){
                return monthNumber;
        }


       //Overload the -- Operator
        Month Month::operator--(int){
        if(monthNumber == 1)
        {
        setNumber(12);
        setName("December");
        }
        else {
        monthNumber++;
        setNumber(monthNumber);
        }
    }
        Month Month::operator--(){
        if(monthNumber == 1)
        {
        setNumber(12);
        setName("December");
        }
        else {
        monthNumber++;
        setNumber(monthNumber);
        }
    }
        //Overload the ++ operator
        Month Month::operator++(int){
        if(monthNumber == 12)
        {
        setNumber(1);
        setName("January");
        }
        else {
        monthNumber++;
        setNumber(monthNumber);
        }
    }
        Month Month::operator++(){
        if(monthNumber == 12)
        {
        setNumber(1);
        setName("January");
        }
        else {
        monthNumber++;
        setNumber(monthNumber);
        }
    }

        //Overloading << and >>
        friend ostream &operator<<(ostream &strm, const Month &obj){
            strm << "# of Month : " << obj.name << " This Corresponds to the month : " << obj.monthNumber << endl;
            return strm;

        }
        //Error here
        //-------------------------------------------------------------------
        //binary'>>' no operator found which takes a right-hand operand of 
        //the type'overloaded-function'(or there is no acceptable conversion)
        //-------------------------------------------------------------------
        friend istream &operator>>(istream &strm, Month &obj) {
            strm >> obj.setNumber >> obj.setName;
            return strm;
        }

};
#endif

source.cpp

#include "Month.h"
#include <cstdlib>
#include <iostream>

using namespace std;

int main(){
    Month coolio, first(1), second("June");
    coolio++;
    second--;
    ++first;

    cout << "Enter the month number: " << endl;
    cin >> coolio;

    cout << coolio;
    cout << second;
    cout << first;

    return 0;
}

【问题讨论】:

  • 我相信你有理由让你的成员成为static。我只是想不出它可能是什么。
  • 您正在尝试读入成员函数。读入数据成员。
  • 去掉头文件中的using namespace std;
  • @PaulMcKenzie:我认为您将 Stack Overflow 与 CodeReview.stackexchange.com 混淆了。
  • 如果你知道错误可能出在哪里,为什么不发布一个精简版的课程来节省大家的时间呢?见how to create an MCVE

标签: c++ operator-overloading overloading


【解决方案1】:

您无法从输入流中读取数据,并将其与方法调用结合使用。您需要将数据读入一个临时的int 和一个临时的string,然后使用这些intstring 调用setter,如下所示:

friend istream &operator>>(istream &strm, Month &obj) {
    int number;
    string name;
    strm >> number >> name;
    obj.setNumber(number);
    obj.setName(name);
    return strm;
}

此外,由于&gt;&gt; 被声明为friend,您可以直接读入obj 的成员变量。

【讨论】:

  • +1,更直接。它是一个 friend ed 运算符。除非有人希望某天有某种隐秘的理由在 setter 中注入恶意活动,否则您可以直接读入 obj.namemonthNumber,因为在调用 setter 之前没有检查 strm
  • 是的,如果流读取失败,您所拥有的完全正确的方法是保持obj 的原始状态。 IE。 if (strm &gt;&gt; number &gt;&gt; name) then 解雇二传手(或直接分配给成员;无论哪种方式)。只是供 OP 思考的食物。
【解决方案2】:

以下是一些关于如何简化程序的建议(这样我们其他人就不必费力地阅读数百行代码):

直接分配给成员

您无需在setNumber 方法中调用setName
直接访问name 变量。

一个文本大小写,一个比较

对于 jUNe 案例,您的代码将失败。
您可以在比较之前将您的月份名称转换为全部小写或全部大写。这会将您的 if-else 阶梯减少一半。
在网上搜索“c++ transform toupper”。

删除月份比较

有一种将月份名称​​映射到数字的奇特技术,但我们不会使用它。您可以改用数组。让数组索引代表月份数:

static const char month_number_to_name[13] =
{
  "Nothing",
  "january", "february", "march", "april", "may", "june",
  "july", "august", "september", "october", "november", "december",
};

// ...
std::cout << "The name of month 10 is: "
          << month_number_to_name[10]
          << "\n";

保存月份名称或编号

无需同时保存月份名称和编号。使用上面的翻译数组,您可以在名称和数字之间进行转换。
我建议保持月份数字变量。如果需要名称,使用月份号获取名称,处理名称。

体积小,缺陷少

编程行业有很多研究表明,程序越长,它就越有可能比较短的程序有更多的缺陷。只考虑打字。输入的字母越多,打字错误的机会就越多。

利用数据结构来减少程序大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2011-01-10
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    相关资源
    最近更新 更多