If a class is written well, you should be able to gleam all relevant information about the class simply by looking at its header.
If one sees that the constructor is marked explicit
:
- What should one assume to be absolutely true about this class?
- What should one assume to be potentially true about this class.
- What sort of bugs could one expect, if
explicit
is violated somehow?
If what I am asking is not clear; In the same way that if I see a member function marked virtual void sneed() = 0;
- Its absolutely true that this is an abstract class
- Its potentially true that this is some sort of factory
- And that if I do not impliment it, the program will not compile.
Thanks.
virtual
example, it is in general not at all likely that it is some sort of a factory. This might be true in the context of particular codebase, but in general, it doesn't have to be a factory in any way. Forexplicit
, you can infer that the devs wanted to prevent implicit conversions in client code.explicit
, you prevent the compiler from making implicit conversions using that constructor. E.g., when a function takes a float, and you type in an int like42
, it is implicitly converted to a float, but if a function takes an int, and you attempt to pass a float like3.14
, you get a warning in C++ and an error in C#, because (a) a loss of data occurs, and you may care about that, and (b) even if you intended to do this, maybe the default rounding/truncation scheme doesn't do what you thought it does. So there's potential for subtle errors. 1/3explicit
on their constructor, it indicates that they thought that implicit conversions (from the type of the constructor argument to the type of the class) would potentially cause more trouble then the convenience of implicit conversion was worth. Exactly why they thought this depends on what the actual class is supposed to represent and how it's meant to be used, and to some extent on their personal preferences. 2/3QObject
, the constructor takes in aQObject*
, a pointer to a parent - which means that the compiler can use it to implicitly "convert" a pointer into a QObject. So, if you accidentally passed some pointer you had to a function that takes a QObject by value, the compiler would implicitly call that constructor to create a new QObject that has the pointer you passed in as a parent - which is probably not what you wanted;explicit
prevents that. (BTW, you didn't mention QObject anywhere before your last comment, so I was talking in general terms) 3/3QObject*
) to some qt object already in memory, and it needs to be assigned (maybe by accident) to a variable or a parameter of typeQObject
, the compiler has to figure out if that's valid. So it will go "Oh, look, there's a constructor that takes a singleQObject*
and spits out aQObject
! Seems like it lets me convert between these two!". The problem is, the compiler is wrong about what this constructor does - it's not meant for conversions. Here's a demo, click the "Fork" btn to edit.