С++ использование явного, предложенного cppcheck

Плохо ли использовать конструктор приведения? В противном случае, почему средство проверки качества кода (в моем случае cppcheck) постоянно предлагало бы добавить явное значение перед конструкторами с одним параметром?

Что, если я хочу сделать

class MyClass {  
 A(int) {}
};

A a = 1;

Если я последую предложениям и напишу

class MyClass {  
 explicit A(int) {}
};

A a = 1; 

вызовет ошибку, но если я воспользуюсь первым, у меня будет предупреждение, что я должен задокументировать, чтобы пройти проверку кода.


person DDS    schedule 22.12.2020    source источник
comment
Такие программы проверки, как cppcheck, проверяют соответствие правилам style. Некоторые рекомендации по стилю не рекомендуют использовать конструкторы приведения с одним аргументом и рекомендуют делать их явными, поскольку это позволяет избежать непреднамеренных неявных преобразований. Суть таких рекомендаций по стилю заключается в требовании документального обоснования использования конструкторов неявного приведения типов всякий раз, когда вы их используете.   -  person Peter    schedule 22.12.2020
comment
Прямое решение - инициализировать с помощью A a{1};   -  person stefaanv    schedule 22.12.2020
comment
Вы можете отключить проверку локально, см., например, cppcheck-inline-suppression.   -  person Jarod42    schedule 22.12.2020


Ответы (2)


Такое неявное преобразование типа класса можно легко использовать без намерения. С этим конструктором преобразования каждая функция или функция-член, которая принимает MyClass в качестве аргумента, также будет принимать int. Поэтому каждый int, переданный такой функции, будет преобразован во временный MyClass, который будет отброшен после завершения функции. Вероятно, это не то, что вы хотите.

person Peter    schedule 22.12.2020

Основные рекомендации C++

C.46: по умолчанию объявить одноаргументный конструкторы явные

Причина

Чтобы избежать непреднамеренных преобразований.

Пример, плохо

class String {
public:
    String(int);   // BAD
    // ...
};

String s = 10;   // surprise: string of size 10

Исключение

Если вам действительно нужно неявное преобразование из типа аргумента конструктора в тип класса, не используйте явное:

class Complex {
public:
    Complex(double d);   // OK: we want a conversion from d to {d, 0}
    // ...
};

Complex z = 10.7;   // unsurprising conversion

См. также: Обсуждение неявных преобразований

person bolov    schedule 22.12.2020