Reputation: 876
so I have a class named Date
which looks like this:
class Date {
private:
UINT month, day, year;
std::string DateToString;
public:
Date(UINT inMonth, UINT inDay, UINT inYear)
: month(inMonth), day(inDay), year(inYear){}
operator PCSTR() {
//essentially just an ostream that takes strings inside it
std::ostringstream formattedDate;
//feed it and convert integers as well
formattedDate << this->month << " / " << this->day << " / " << this->year;
//get content of stream as a pointer with str() method
//store the pointer in local var to avoid it to being invalidated after RET was hit and cout not able to display
this->DateToString = formattedDate.str();
return DateToString.c_str();//convert that ostringstream string to a PCSTR
}
}
Note: I'm using Windows data types with PCSTR
being a const char*
and UINT an unsigned int
.
Now this class serves as a date instantiation class: Date test(1, 10, 2020)
, I've created the operator PCSTR()
member method to be able to use it in cout
, because the latter will use the most suited operator conversion to be able to display an object, and here we use const char*/PCSTR
because cout
does not have any problems displaying them. So if I do cout << test;
it displays 1/10/2020
.
Now on my code editor it tells me 'operator const char *' must be marked explicit to avoid unintentional implicit conversions
, I don't understand, isn't that what we want, if I mark it explicit then I must cast the object, why can't I just leave it like that? What other conversions can happen with const char*
?
Thanks in advance.
Upvotes: 0
Views: 272
Reputation: 17454
Now on my code editor it tells me 'operator const char *' must be marked explicit to avoid unintentional implicit conversions
That's right. This is just a warning, but it's a good one!
I don't understand, isn't that what we want
No!
if I mark it explicit then I must cast the object
That's a good thing. It avoids accidents.
why can't I just leave it like that?
You can if you want to. But I recommend that you don't.
Upvotes: 1
Reputation: 2679
I can think of one unintentional implicit conversion here. If you were to accidentally write
Date date;
// ...
if (date) { /* ... */ }
the compiler could first convert date
to const char*
, and then const char*
to bool
, and this would be a difficult-to-debug situation. The explicit
operator protects against this situation.
There's a better way to define how your class should be printed to std::cout
:
class Date {
// ...
std::string toString() const {
// ...
return formattedDate.str();
}
}
std::ostream& operator<<(std::ostream& out, const Date& date) {
return out << date.toString();
}
If you must use a conversion operator, why not make it explicit and convert where needed? It would be easier to see from the code exactly what is happening.
std::cout << static_cast<const char*>(date);
Upvotes: 4