没有从“ int”到“ Time”的可行转换

时间:2018-07-30 13:52:21

标签: c++ operator-overloading

我在用户定义的+运算符中出错:

#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();  
}
  

注意:候选构造函数(隐式副本构造函数)不可行:第一个参数没有从'int'到'const Time&'的已知转换

我该如何解决?

2 个答案:

答案 0 :(得分:0)

您可以通过将operator+更改为

来解决问题
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;
}

首先,按照您的示例计算总秒数。然后创建一个临时Time。由于无法从一个int创建它,因此它的属性是一一设置的。

答案 1 :(得分:0)

按照书面规定,为t2赋值的行假定了当前缺少的几件事:

  1. 可以添加一个int和一个Time实例(通过operator +);
  2. 从int到Time类有一个隐式转换。

这两个代码都不由当前编写的代码定义。

解决方案:这可能比您需要的要彻底,但是它确实说明了运算符重载的精妙之处,以及考虑使用类的不同可能方式所需的工作。

我所做的一个重要假设:当前编写Time :: operator int()的计算方式意味着将int值解释为秒数。这些类型的假设应清楚且明确地记录在评论中。

写成员运算符+ =(int)定义如何将int解释为Time值。

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;
}

现在编写两个非成员友元函数以根据Time :: operator + =()实现二进制运算符。这涵盖了操作数顺序(整数+时间)或(时间+整数):

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;
}

可选:您还可以编写另一个ctor,以根据Time :: operator + =()来定义从int到Time的逆转换:

explicit Time::Time(int secs)
{
    // Initialize members to zero.
    h = m = s = 0;
    // Add specified seconds.
    *this += secs;
}

可选:即使有上述所有情况,您仍然尚未在两个Time实例之间定义二进制操作符+()。这将达到目的:

friend Time operator+(const Time& tleft, const Time& tright)
{
    Time sum(tleft);
    return sum += static_cast<int>(tright);
}

请注意,考虑从几秒钟到几分钟到几分钟到几小时到几小时的溢出的计算逻辑封装在单个位置运算符+ =(int)中。

最后一点:Time :: operator int()转换应声明为“ const”成员函数,因为它不会更改其成员值。由于上面的转换是在static_cast <>表达式中使用的,因此编译上面的operator +(Time,Time)函数是必需的。

// Conversion from Time to int as total seconds.
operator int() const
{
    return (h*3600 + m*60 + s);
}