【问题标题】:C++ operator overloading and accessing private data variablesC++ 运算符重载和访问私有数据变量
【发布时间】:2017-10-23 18:48:56
【问题描述】:

我是 C++ 新手,我正在编写一个类来实现日期函数。 该程序有两个非成员函数bool printDate(const Date& d)string intToString(const int& n)和两个用于重载运算符<< and >>的友元函数

代码链接是https://repl.it/NC2H/37

我不断收到类似的错误

'std::__cxx11::string Date::month' is private within this context `,

` ambiguous overload for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const Date')`
and 

`note: declared private here`

代码:

     #include<iostream>
      #include<vector>
      #include<string.h>
      #include<ctype.h>
      #include<algorithm>
      using namespace std;

      const vector<string> months{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };


       string intToString(const int& n){
        return to_string(n);           //inbuilt function
      }


      class  Date{
        //Private members
        string month;
        int day;
        int year;


        bool isValidMonth() const{
          return day==daysInMonth(m);
        }

        int daysInMonth(const string& m) const{
          vector<string>::iterator m_index;
          if(find(months.begin(),months.end(),m)!=months.end()){
            m_index=find(months.begin(),months.end(),m);
          }
          int month_index=distance(months.begin(),m_index)+1;
          switch(month_index)
          {
            case 2: return isLeapYear()?29:28;

            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                   return 31;

            default:
                   return 30;
          }

        }
        bool isLeapYear() const{
          if(year%4==0){
            if(year%100==0 && year%400==0){       //2000 is leap year but 1900 is not
                return true;
              }
            else{
              return false;
            }
          }
          else{
            return false;
          }
        }
        string toString(){
            string result_date;
            result_date=intToString(day)+"-"+month+"-"+intToString(year);
            return result_date;
        }
        public:

        friend istream& operator >>(istream& is, Date& d);
        friend ostream& operator <<(ostream&os ,const Date);
        //public constructor
        Date(const string& m="January",const int& d=1,const int&y=2000){
          month=m;
          day=d;
          year=y;
        }

        void setMonth(const string& m){
            month=m;
        }
        void setDay(const int& d){
            day=d;
        }
        void setYear(const int& y){
            year=y;
        }

        string getMonth()const{
            return month;
        }
        int getDay() const{
          return day;
        }
        int getYear() const{
            return year;
        }
        void Month(){
            if(!month.empty())
            {
                month[0]=toupper( month[0] );
                for(int i=1;i<month.length();++i)
                    month[i]=tolower(month[i]);
            }
        }
        bool isValidDate() const{
            //calls isValidMonth() to check if days match 
            if(isValidMonth() ){
              return true;
            }
            return false;
        }


      };




       istream & operator >>(istream & is, Date& d){
        //overloads the >>operator, which reads 
        cout<<"\n Enter the day of  the date \n";
        cin>>d.day;
        cout<<"\n Enter the month of the date \n";
        cin>>d.month;
        cout<<"\n Enter the year of the date \n";
        cin>>d.year;
        return is;
      }

      ostream & operator <<(ostream & os ,const Date& d){
        os<<d.day<<"."<<d.month<<"."<<d.year;
        return os;
      }
      bool printDate(const Date& d){
       // if(!d.isValidDate()){
       if(!d.isValidDate()){
          cerr<<"( "<<d<<" ): not valid date";
          return false;
        }
        cout<<"( "<<d<<" )";
        return true;
      }
      int main(int argc, char const *argv[])
      {
        // code for testing purposes 
        Date defaultDate;
        printDate(defaultDate); 
        cout<<endl;
      /*    
        Date moonLanding("jul",20,1969);
        printDate(moonLanding); 
        cout<<endl;
        moonLanding.setMonth("july");
        printDate(moonLanding); 
        cout<<endl;

        Date leapDay("Ferbruary",29,2001);
        printDate(leapDay); 
        cout<<endl;
        leapDay.setDay(28);
        printDate(leapDay);
        cout<<endl;

        Date d;
        cout<<d.getMonth()<<" "<<d.getDay()<<", "<<d.getYear<<endl;

        d.setMonth("July");
        d.setDay(4);
        d.setYear(1776);
        printDate(d);
        cout<<endl;

        while(cin>>d){
          d.Month();
          bool flag=printDate(d);
          cout<<endl;
          if(flag) cout<<d.toString()<<endl;
        }
      */    
        return 0;
      }

程序运行时的错误是:

main.cpp: In function 'std::ostream& operator<<(std::ostream&, const Date&)':
main.cpp:133:17: error: 'int Date::day' is private within this context
           os<<d.day<<"."<<d.month<<"."<<d.year;
                 ^~~
main.cpp:19:14: note: declared private here
          int day;
              ^~~
main.cpp:133:29: error: 'std::__cxx11::string Date::month' is private within this context
           os<<d.day<<"."<<d.month<<"."<<d.year;
                             ^~~~~
main.cpp:18:17: note: declared private here
          string month;
                 ^~~~~
main.cpp:133:43: error: 'int Date::year' is private within this context
           os<<d.day<<"."<<d.month<<"."<<d.year;
                                           ^~~~
main.cpp:20:14: note: declared private here
          int year;
              ^~~~
main.cpp: In function 'bool printDate(const Date&)':
main.cpp:139:23: error: ambiguous overload for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const Date')
             cerr<<"( "<<d<<" ): not valid date";
             ~~~~~~~~~~^~~
main.cpp:132:19: note: candidate: std::ostream& operator<<(std::ostream&, const Date&)
         ostream & operator <<(ostream & os ,const Date& d){

【问题讨论】:

  • "该类有两个非成员函数" - 任何类都只能有成员函数。:)
  • 如果您唯一的问题是&gt;&gt; 运算符,那么转储大量代码的目的到底是什么,其中包含与当前问题无关的所有成员函数?
  • 错误信息有什么不清楚的地方? 1) 你试图在ostream &amp; operator &lt;&lt;(ostream &amp; os ,const Date&amp; d) 中使用私人成员,而它没有被标记为朋友。 2) 任何可以用const Date&amp; 调用的东西,也可以用const Date 调用,反之亦然。因此 - 模棱两可的调用错误。
  • 提取运算符&gt;&gt; 不应与用户交互。它应该从istream 参数中读取整个日期,而不是从cin,最好采用插入运算符&lt;&lt; 编写的格式。

标签: c++ oop c++11 operator-overloading


【解决方案1】:

朋友声明与实际操作员不符:

friend ostream& operator <<(ostream&os ,const Date);
...
ostream & operator <<(ostream & os ,const Date& d)

请注意,实际的运算符接受引用。

【讨论】:

    【解决方案2】:

    作为对朋友问题的风格修复,添加一个名为 print 的公共成员函数,它实现了流式传输,并且因为它是一个成员,所以它可以访问那些讨厌的私有变量:

    ostream& print(ostream& str)const
    

    然后你的外部运算符

    ostream& operator <<(ostream& str, const MyClass& inst)
    {
        return inst.print(str);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多