问题
I am having an error in a user defined +
operator:
#include <iostream>
using namespace std;
class Time{
int h;
int m;
int s;
public:
Time();
Time(int x,int y, int z) {
h=x;
m=y;
s=z;
}
operator int() {
return(h*3600 + m*60 + s);
}
void display() {
cout<<h<<endl;
cout<<m<<endl;
cout<<s<<endl;
}
};
int main(){
Time t1(2, 3, 4);
Time t2 = 200 + (int)t1;
t2.display();
}
note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Time &' for 1st argument
How can I fix this?
回答1:
You can fix your problem by changing your operator+
to
Time operator+(int total){
total=total+h*3600+m*60+s;
Time temp;
temp.h = total / 3600;
temp.m = (total % 3600) / 60;
temp.s = total % 60;
return temp;
}
First the total number of seconds is calculated as in your example. Then a temporary Time
is created. Since it can't be created from one int
, its properties are set one by one.
回答2:
As written, the line where t2 is assigned a value assumes a couple things that are currently missing:
- an int and a Time instance can be added (by operator+);
- there's an implicit conversion from int to the Time class.
Neither of these are defined by the code as presently written.
Solution: This may be more thorough than you might need, but it does illustrate subtleties of operator overloading and the work needed to consider different possible ways a class might be used.
An Important assumption I made: The way the calculation of Time::operator int() is currently written implies that the int value should be interpreted as the number of seconds. These type of assumptions should be clearly, and explicitly documented in a comment.
Write the member operator+=(int) to define how an int is interpreted as a Time value.
Time& Time::operator+=(int secs)
{
// Account for overflow (s >= 60 and m >= 60).
int totalSecs = (h*3600) + (m*60) + s + secs;
// Breakdown new total into hours, minutes, and seconds.
h = totalSecs / 3600;
m = (totalSecs - (h*3600)) / 60;
s = totalSecs - (h*3600) - (m*60);
return *this;
}
Now write the two non-member friend functions to implement binary operators in terms of Time::operator+=(). This covers either operand order (int + Time) or (Time + int):
friend Time operator+(const Time& t, int secs)
{
Time sum(t);
return sum += secs;
}
friend Time operator+(int secs, const Time& t)
{
Time sum(t);
return sum += secs;
}
Optional: You may also write another ctor to define the inverse conversion from int to Time in terms of Time::operator+=() too:
explicit Time::Time(int secs)
{
// Initialize members to zero.
h = m = s = 0;
// Add specified seconds.
*this += secs;
}
Optional: Even with all this above, you still haven't yet defined a binary operator+() between two Time instances. This will do the trick:
friend Time operator+(const Time& tleft, const Time& tright)
{
Time sum(tleft);
return sum += static_cast<int>(tright);
}
Note that the calculation logic of considering overflow from seconds to minutes and minutes to hours is encapsulated in a single location operator+=(int).
One last point: The Time::operator int() conversion should be declared as a 'const' member function because it doesn't alter its member values. This is required in order for the above operator+(Time,Time) function to compile since the conversion is used in the static_cast<> expression.
// Conversion from Time to int as total seconds.
operator int() const
{
return (h*3600 + m*60 + s);
}
来源:https://stackoverflow.com/questions/51595551/no-viable-conversion-from-int-to-time