在不讨论它是否是一个好主意的情况下,如果他们要将内置的C ++数据类型封装到他们自己的类中,那么将面临什么类型的缺点(性能或其他方面)。例如,类似于Java和C#,int数据类型将拥有自己的类Int,使用内联运算符重载它。与Single,Double,Long等相同。
答案 0 :(得分:5)
没有任何好处。你无法实现相同的行为和表现。
缺点:
当您不想使用多种类型重载Math类时,如果只需要Integer或Real就足够了,这可能很有用。
你的Java陷入困境。
C ++采用模板方法:
template<typename A_type, typename B_type>
auto math_operation(A_type a, B_type b) -> decltype(a + b * 2) {
return a + b * 2;
}
现在你有一个适用于支持正确运算符的任何类型的函数。这适用于内置类型和类Int128
。
答案 1 :(得分:2)
清晰度会受到影响,而且大部分都是这样。
如果你有一个智能编译器,一个只包装int
并且不会改变任何操作的类很可能完全内联。如果您没有将构造函数定义为显式,那么您甚至可以为f(15)
编写void f(OurVerySpecialInt i)
。如果有的话,你将很难将非常特殊的Ints传递给现有的函数。
如果你的意思是一个类层次结构而不仅仅是一个类,那么情况就会大不相同。您希望Numeric
成为抽象基类,并Int
和Double
从中派生出来吗?在这种情况下,请重新考虑。你不仅可能最终得到明显更慢的代码,而且还没有办法让这种通用和同时保持理智。
让我们考虑一个重载Numeric
的课程operator+
。运算符是非成员(应该是),然后它不能是虚拟的:因此,它必须调用Numeric
的虚拟成员函数。但是哪一个? Double() + Double()
会返回Double
吗?那么Double() + Int()
呢?那么Double() + Rational()
呢?在前两种情况下,您可以说“Double
,当然,因为更多可能的值”,但在最后一种情况下不起作用:如果Double
是64位且Rational
是两个32位整数的商,每个都有不能在另一个中表示的值(例如正无穷大和0.3)。
除此之外,您的功能可以承诺很少。 Int32 i = 250; i += 250;
后我的价值是多少?我认为它是500
;怎么样Int8 = 250; Int8 += 250;
?那么Numeric* p = new Int8(250); *p += 250;
呢。你不能神奇地使*p
更大,所以你要么犯错误要么溢出;基本上,如果p
是某些Numeric*
,你就无法知道*p += 50000;
会做什么:按预期工作或溢出/错误输出,你也不知道你是不是执行*p += 5.3
时会失去精确度。
如果通过使条件更严格来修复这些错误,最终会得到某种不需要任何继承的Rational
或BigInt
类;所有行为都是如此严格规定(因为它应该与数学实体一起)从中衍生出来并不会真正让你改变任何东西。
如果这还不够参数,请注意,如果您为Numeric
类提供任何虚拟方法,则所有派生类都将具有vtable(在常见实现下)。这意味着你的班级的每个实例都需要比平时多一点的空间,并且让你的所有数值都是正常大小的两倍会对你的工作造成很大影响。