虽然您可以继续定义“强制转换为浮动”方法的答案,但我相信为了您自己的利益,您最好开始使用公共 API 来实现其他行为。
一般来说,一个简单的“强制转换”不会成功(例如,如果MyFloat
是,会发生什么MyMatrix
?)。
下面的方法当然更冗长,但它强调你应该“吃你自己的食物”,这意味着你应该尝试基于你自己的公共接口实现额外的行为,而不是一堆晦涩的隐式强制转换或friend
函数。如果您使用自己的 API:您将了解它的局限性,并且如果您进行修改,可能会节省对主类的重新编译。
此外,假设您想要计算对您的类的访问(或以其他方式控制对基础值的访问):使用强制转换运算符,您需要复制代码 inoperator float()
和 in float value()
。
所以,这是我的谦虚建议,它看起来更长,但根据我的口味,更好地反映了 OO 设计原则。
#include<iostream>
class MyFloat {
public:
MyFloat(float value):
m_value(value) { }
float value() const {
return m_value;
}
private:
float m_value;
};
// Eat your own food: implement functions using your public interface
// until proven need to do otherwise. This will help you assess the
// usability of your API.
float operator+(const MyFloat& lhs, const MyFloat& rhs) { return lhs.value() + rhs.value(); }
float operator+(const MyFloat& lhs, float rhs) { return lhs.value() + rhs; }
float operator+(float lhs, const MyFloat& rhs) { return lhs + rhs.value(); }
// See, now I can define another operator without need to recompile my
// class (this could have been placed in another file)
std::ostream& operator<<(std::ostream& os, const MyFloat& mf) {
os<<"MyFloat("<<mf.value()<<")";
return os;
}
int main() {
MyFloat x = 3.5; // would not work if I had declared the constructor as "explicit"
MyFloat y = x + 3.2;
MyFloat z = 3.4 + y;
std::cout<<x<<", "<<y<<", "<<z<<std::endl;
}
输出(用 编译g++ example.cpp -Wall -Wextra
):
MyFloat(3.5), MyFloat(6.7), MyFloat(10.1)