Error while trying to overload Operators with dates

Asked

Viewed 238 times

-3

I’m trying to overload operators for dates, but if I use a double overload it gives error.

What I actually want to do is that if the user uses a separator defining a format he accepts and if the user does not use it takes the default format defined.

#include <iostream>

class Date   {  
    int dia, mes, ano;
    std::string sep; public:  

    Date(int _d, int _m, int _a, std::string _sep): dia(_d), mes(_m), ano(_a), sep(_sep){}

    Date(int _d, int _m, int _a): dia(_d), mes(_m), ano(_a){}  

    friend std::ostream& operator<<(std::ostream& os, const Date& date); };  

std::ostream& operator<<(std::ostream& os, const Date& sepdate)   {  
    oss << sepdate.dia << sepdate.sep << sepdate.mes << sepdate.sep << sepdate.ano << "\n\n";  
    return oss;   }  

std::ostream& operator<<(std::ostream& os, const Date& date)   {
    os << date.dia << "/" << date.mes << "/" << date.ano << "\n\n";
    return os;   }


int main()   {  
    Date sepdate(01, 01, 2017, "-");
    std::cout << "\n\tThe date in sep " << sepdate << std::flush;

    Date date(07,07,2017);
    std::cout << "\n\tThe date is " << date << std::flush;    }

/* Saida:    bash-4.3$ ./operator

        The date in sep 1-1-2017


        The date is 772017
*/

Ele teria que retornar a seguinte saida:
/* Saida:    bash-4.3$ ./operator

        The date in sep 1-1-2017


        The date is 7/7/2017
*/
  • Do pq not change the constructor and use only one output operator ? ... Date(int _d, int _m, int _a): dia(_d), mes(_m), ano(_a), Sep("/") {}

3 answers

1

The program shown neither compiles, because there is duplicate definition of the output operator. Also the formatting is hideous, it is not a typical formatting used with C++.

Obs. numeric literals starting with '0' indicate octal numbers. Not to be used to enter decimal numbers such as '01' and '07' above.

Below an improved version, which compiles and shows the date bars in the output.

#include <iostream>

class Date
{  
   int dia, mes, ano;
   std::string sep;

   public:  
      Date(int _d, int _m, int _a, std::string _sep): dia(_d), mes(_m), ano(_a), sep(_sep) { }

      Date(int _d, int _m, int _a): dia(_d), mes(_m), ano(_a) { }

      friend std::ostream& operator<<(std::ostream& os, const Date& date);
};

// std::ostream& operator<<(std::ostream& os, const Date& sepdate)
// {
//    os << sepdate.dia << sepdate.sep << sepdate.mes << sepdate.sep << sepdate.ano << "\n\n";  
//    return os;
// }

std::ostream& operator<<(std::ostream& os, const Date& date)
{
   os << date.dia << "/" << date.mes << "/" << date.ano << "\n\n";
   return os;
}

int main()
{  
   Date sepdate(1, 1, 2017, "-");
   std::cout << "\n\tThe date is sep " << sepdate << std::flush;

   Date date(7,7,2017);
   std::cout << "\n\tThe date is " << date << std::flush;
}
  • so this way this right now stayed as I thought because my intention was to use operator overload so that if the user did not inform any separator himself define one by default only receiving input data, now if he wanted to put anything as date separator that he could set to his liking now it’s cool... as for the mistakes I was aware of some mistakes there only posted with the mistakes even to see if someone gave a read on the code and sent the real if it was or had some way to maintain two exit operators with different functions.

  • but now it worked out thanks to the force ai needed an example like this because I’m thinking of creating a library for use and formatting dates and times, I am also aware of your tip to write short and more legible lines but to understand and learn the language for now I use it this way, nor use the namespace that is for myself to understand who is Friend from whom and who inherits from whom within the libraries of C++.

  • I already got code in C++ that used the function time() without including the library <ctime> so I went to give a search and the same is already a include inside <iostream> so it is not always necessary to include that library mount that will not even be used... But thanks for the help...

1


First, the second constructor is not setting the separator (the string sep) with a default value defined by you. The assigned separator is therefore "".

Date(int _d, int _m, int _a, std::string _sep): dia(_d), mes(_m), ano(_a), sep(_sep){}
Date(int _d, int _m, int _a): dia(_d), mes(_m), ano(_a){} 

I think you prefer to set the default value "/", so it is not necessary to create any additional method (neither the constructor nor that operator) which is only to deal with the case of non-definition of the separator. You can stay like this:

Date(int _d, int _m, int _a, std::string _sep="/"): dia(_d), mes(_m), ano(_a), sep(_sep){}

.

Second, just after declaring the first operador<< without body, you closed bracket without opening, it is syntax error. I do not know how you could compile so...

friend std::ostream& operator<<(std::ostream& os, const Date& date); }; 

.

Third, the first definition of the operator has typing error. The parameter is os but the code uses oss, which was not declared as parameter. It is semantic error. I also don’t know how you compiled with this error...

std::ostream& operator<<(std::ostream& os, const Date& sepdate)   {  
    oss << sepdate.dia << sepdate.sep << sepdate.mes << sepdate.sep << sepdate.ano << "\n\n";  
    return oss;   }   

.

Fourth, the two definitions of operators have the same signature:

ostream& operator<<( ostream& , const Date& ) ;

and that makes the operator ambiguous even to whom would invoke the friend. I don’t think we can separate methods of the same signature between friend and not friend, for me this is semantic error, but if compiled so I can be wrong...

.

Anyway, to finish I recommend not only fix this but also adopt better programming practices to make your code more readable. These two definitions of methods, for example, are very illegible.

Date(int _d, int _m, int _a, std::string _sep): dia(_d), mes(_m), ano(_a), sep(_sep){} 

std::ostream& operator<<(std::ostream& os, const Date& sepdate)   {  
    oss << sepdate.dia << sepdate.sep << sepdate.mes << sepdate.sep << sepdate.ano << "\n\n";  
    return oss;   }  

Avoid leaving lines of code too long, use alternatives that reduce their size (even with more lines). Also use spaces to better separate elements to make them easier to read. It’s also good to use the using namespace std ; to reduce the code. Identify the code correctly and avoid keys in the same row of codes that they involve. If I do all this, the parts I just showed might look like this, for example.

Date( int _d , int _m , int _a , string _sep ):
dia( _d ) ,
mes( _m ) ,
ano( _a ) ,
sep( _sep ) {
    // Sem código.
} 

ostream& operator<<( ostream& os , const Date& sepdate ) {  
    os << sepdate.dia << sepdate.sep << sepdate.mes ;
    os << sepdate.sep << sepdate.ano << "\n\n" ;
    return os ;
}  

It’s gotten a lot better, don’t you think? If it’s not for that, it might just be like this.

Date( int _d , int _m , int _a , std::string _sep ):
dia(_d) , mes(_m) , ano(_a) , sep(_sep) { } 

std::ostream& operator<<( std::ostream& os , const Date& sepdate ) {  
    os << sepdate.dia << sepdate.sep << sepdate.mes ;
    os << sepdate.sep << sepdate.ano << "\n\n" ;
    return os ;
}  

Anyway, my code would look like this.

# include <iostream>

class Date {  
   int dia , mes , ano ;
   std::string sep ;

   public:  

      Date( int _d , int _m , int _a , std::string _sep="/" ):
         dia(_d) , mes(_m) , ano(_a) , sep(_sep) { }

      friend std::ostream& operator<<( std::ostream& os , const Date& date ) {
         os << date.dia << date.sep << date.mes ;
         os << date.sep << date.ano << "\n\n" ;
         return os ;
      }
} ;

int main( int ac , char **av ) {  
   Date sepdate( 1 , 1 , 2017 , "-" ) ;
   std::cout << "\n\tThe date is sep " ;
   std::cout << sepdate << std::flush ;
   Date date( 7 , 7 , 2017 ) ;
   std::cout << "\n\tThe date is " ;
   std::cout << date << std::flush ;
}

0

If I understand your question correctly, you want the "/" on each item on the date.

To do this, you must format your text:

std::put_time(&date, "%d/%m/%Y");
  • so I use Std::put_time in another class example where I manipulate strings for date but want to do this with operator overload would be possible to do this with overload where the same class can return both cases without having to use some specific function for it?

  • @dark777 How so return both cases? What would be the cases?

  • review the case there is the second option

  • Man, if there’s a lot of wrong people and you’re the only one, it’s good to investigate, because maybe you’re the one who’s wrong.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.