Ясность пострадает, и это все по большей части.
Если у вас есть умный компилятор, класс, который просто оборачивает int
и не изменяет ни одну из операций, вполне вероятно, станет полностью встроенным. Если вы не определите конструктор как явный, вы даже сможете написать f(15)
для void f(OurVerySpecialInt i)
. Однако вам будет сложнее передать свои Особые Интты существующим функциям, если они есть.
Вещи очень разные, если вы имеете в виду иерархию классов, а не просто класс. Вы хотите, чтобы 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 (в соответствии с общими реализациями). Это означает, что каждому экземпляру вашего класса потребуется немного больше места, чем обычно, и если все ваши числовые значения будут в два раза больше нормального размера, это может сильно снизить производительность в зависимости от того, что вы делаете.