Если у вас есть конструкторы, которые можно вызывать только с одним аргументом, вы фактически создали оператор неявного преобразования. В вашем примере, где требуется CFixed
, можно передать как int
, так и float
. Это, конечно, опасно, потому что компилятор может молча генерировать код, вызывающий неправильную функцию, вместо того, чтобы лаять на вас, когда вы забыли включить объявление какой-либо функции.
Поэтому хорошее практическое правило гласит, что всякий раз, когда вы пишете конструкторы, которые могут быть вызваны только с одним аргументом (обратите внимание, что этот foo(int i, bool b = false)
также может вызываться с одним аргументом, даже если он принимает два аргумента) , вы должны сделать этот конструктор explicit
, если только вы не хотите, чтобы неявное преобразование вступило в силу. explicit
конструкторы не используются компилятором для неявных преобразований.
Вы должны изменить свой класс на это:
class CFixed
{
explicit CFixed( int );
explicit CFixed( float );
};
Я обнаружил, что из этого правила очень мало исключений. (std::string::string(const char*)
довольно известный.)
Редактировать: Извините, я упустил момент, когда не допускал неявных преобразований из int
в float
.
Единственный способ предотвратить это - предоставить операторам также float
.