C ++运算符重载和访问私有数据变量

时间:2017-10-23 18:48:56

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

我是C ++的新手,我正在编写一个实现日期函数的类。 该程序有两个非成员函数bool printDate(const Date& d)string intToString(const int& n)以及2个用于重载运算符<< 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){

2 个答案:

答案 0 :(得分:3)

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

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

请注意,实际操作员接受参考。

答案 1 :(得分:0)

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

.transition

然后你的外部运营商&lt;&lt;变得微不足道:

ostream& print(ostream& str)const