今天又开始学习万能的时间魔法。毫无疑问,这次给自己挖了个巨坑,一时半会儿是无法填平了。今天一不小心踩了一片雷区,一时间爆炸不断,此起彼伏。到现在整个人的状态都有点懵。忙活了一阵,总算是初步实现了时间刻度模型,具备时间进位功能,同时可以操作增减。
class TimeScale
{
protected:
TimeScale *parent = nullptr;
TimeScale *child = nullptr;
int value;
int max;
/// @brief 设置值
/// @param result
virtual void setValue(int result);
/// @brief 处理进位
/// @param result
virtual void handleCarry(int carry);
/// @brief 重新检查子刻度,处理特殊逻辑
virtual void recheckChild();
public:
TimeScale(int value, int max);
TimeScale(TimeScale *parent, int value, int max);
/// @brief 添加子类
/// @param child
void setChild(TimeScale *child);
virtual void operator+(const int i);
virtual void operator-(const int i);
operator int();
/// @brief 获取当前值
/// @return
const int getValue();
/// @brief 获取高级刻度
/// @return
const TimeScale *getParent();
virtual ~TimeScale();
};
void datetime::TimeScale::handleCarry(int carry)
{
if (parent)
{
if (carry < 0)
{
parent->operator-(0 - carry);
}
else
{
parent->operator+(carry);
}
}
}
void datetime::TimeScale::setValue(int result)
{
value = result % max;
}
void datetime::TimeScale::recheckChild()
{
if (child)
{
child->recheckChild();
}
}
datetime::TimeScale::TimeScale(int value, int max) : value(value), max(max)
{
}
datetime::TimeScale::TimeScale(datetime::TimeScale *parent, int value, int max) : parent(parent), value(value), max(max)
{
}
void datetime::TimeScale::setChild(datetime::TimeScale *child)
{
this->child = child;
}
void datetime::TimeScale::operator+(int i)
{
int result = value + i;
setValue(result);
int carry = result / max;
if (carry > 0)
{
handleCarry(carry);
}
else
{
recheckChild();
}
}
void datetime::TimeScale::operator-(int i)
{
int carry = i / max;
int result = value - i % max;
setValue(result >= 0 ? result : result + max);
if (result < 0)
{
carry++;
}
if (carry > 0)
{
handleCarry(0 - carry);
}
else
{
recheckChild();
}
}
datetime::TimeScale::operator int()
{
return value;
}
const int datetime::TimeScale::getValue()
{
return this->value;
}
const datetime::TimeScale *datetime::TimeScale::getParent()
{
return parent;
}
datetime::TimeScale::~TimeScale()
{
}
通过模拟十进制进位测试,目前功能可用,后续可能还需要进一步优化。然后总结一下目前踩到的雷,有些纯属学艺不精,记下以备查找。
- 问题:overloaded 'operator=' must be a non-static member function
在实现时间刻度模型的时候,后续考虑实现如同int yearValue = year这样时间刻度类型和整形之间的隐式转换,所以在命名空间下定义了如下的操作符重载操作:
int& operator=(int& target, TimeScale& scale);
当我编译运行的时候我收到上述的错误。起先我还以为是语法错误,但是后面发现这个c++中关于重载操作符的一个比较重要的知识点。通常我们所熟知的+,-,*,/,=等操作符可以分为成员操作符和非成员操作符。成员操作符顾名思义只能定义在类的内部,而非成员操作符则不受该限制。
那么问题来了,我想让时间刻度类可以隐式地转换为int,应该如何操作呢?今天又学到一招,使用类型转化操作重载,如下面这样子:
operator int();
- 问题: 'this' argument to member function 'xxxxxx' has type 'const xxxx', but function is not marked const
这个问题在于起先我讲TimeScale的成员parent和child定义为const TimeScale*指针类型。同时定义下面两个方法:
/// @brief 设置值
/// @param result
virtual void setValue(int result);
/// @brief 处理进位
/// @param result
virtual void handleCarry(int carry);
在handleCarry和recheckChild方法中,通过parent和child调用了非const operator操作符方法。这种方式不被c++允许。目前,我还没有理解处理这个问题的方法,所以暂时讲const标识取缔了。
- 问题:conversion function cannot have a return type
这个问题比较简单,通常就是小白新手才会犯的错误。原因是我刚开始定了转换操作重载函数时候,给重载函数添加了饭回类型如下:
int operator int();
而事实上,不需要任何显示的返回类型,只需如下即可:
operator int();
cpp代码文件里的实现也很简单:
datetime::TimeScale::operator int()
{
return value;
}