This is a matter of personal preference, there are no implications on what these two options do or invoke. As I guess it is common sense to not repeatedly type types as in
const int three = static_cast<int>(3.14);
const Sub* sub = dynamic_cast<Sub*>(&baseInstance);
which is often written down with auto
as
// better, the concrete type is only typed once, less maintainance "burden":
const auto three = static_cast<int>(3.14);
const auto* sub = dynamic_cast<Sub*>(&baseInstance);
you could take this argument and transfer it to the example snippet above:
MyClass(const UserDefinedType &obj = UserDefinedType());
Here, the type is spelled out twice, and that's undesirable. Hence, I recommend going with
// Shorter, not less readable - a default-constructed default instance:
MyClass(const UserDefinedType &obj = {})
Note that in the special case of constructors, it is equally simple to use in-class member initialization together with a default constructor and an additional overload, e.g.
MyClass {
public:
MyClass() = default;
explicit MyClass(const UserDefinedType& obj) : m_member{obj} {}
private:
UserDefinedType m_member = {};
};
The advantage of this approach is the low likelihood of introducing bugs when a new constructor overload is added to the class. But this is a nuance. Note, however, that I've marked the single-argument ctor explicit
, which is usually considered good practice to prevent accidental implicit conversions.