Do you usually prefix your classes with the letter 'C' or something else?

Started by
89 comments, last by Ravyne 7 years, 10 months ago

Yes, Boost is very cool library, i hear, some boost features, include in new CPP specifications. Thanks. But i'm interested why microsoft in MFC uses C prefix, if it not correct for CPP?

Because it was the fashion of the day when MFC was introduced.

It was a different time then -- most significantly, IDEs were much more primitive and had no or poor support for modern conveniences like intellisense or auto-completion. It was believed by some people and organizations in those days that encoding that kind of information into type, function, and variable names would provide a similar benefit to what we get today from intellisense and other modern IDE features. Whether it was a great idea at the time or not is a matter for debate, but times have changed. Just because something was a good idea yesterday, doesn't make it a good idea today.

Even assuming that the supposed benefit was real, this approach is brittle because what's encoded in the name often comes to disagree with reality as the code evolves. Take the C-prefix of classes you promote -- what if, after some reflection, you decide to refactor that class into a struct instead, because you thought you'd need some member functions but it turns out you didn't after all (and if you're pedantic enough that classes are prefixed with C, you're probably also pedantic enough that 'structs don't have member functions'). Now, normally all you'd have to do to refactor this situation is to change the declaration/definition to use the struct keyword, rather than class and you'd be done, but because you duplicated this information in the name of the type, the name now disagrees with the reality of what the type is, and you need to go and change it everywhere you use a parameter or variable of that type.

Now, that's not a great example because structs and classes are semantically close enough in C++ that it may not actually matter, semantically, even if the cosmetic difference bothers you--but if you care enough that "C belongs on every class", then you can't back out of cosmetic correctness now.

I would go one further to say that repeating type information by encoding it into the name of a code entity is a violation of the DRY (Don't Repeat Yourself) principle, and is bad for all the same reasons -- primarily that every time you repeat the same information, you introduce another opportunity for disagreement to seep in, which undermines the conceptual purity of what you have to reason with day in and day out. If you don't repeat yourself, there's only one source of information and you know that it is the one and only truth; thus, the purity of what you have to reason with is never compromised.

There's a lesser-known, but more correct, version of such prefixes (the true form of hungarian notation) -- where the prefixes encoded usage information rather than type information -- for example, you might have floating point values where one usage represents radians, and another that represents degrees of an arc. Programmers realized that those types, in a language like C (and still C++ to this day), were syntactically interchangeable (e.g. Compiler don't care) but not semantically interchangeable (e.g. Program do care). This is because typedefs in C and C++ aren't strong -- that is, a typedef is just another word for the its type, but is not a distinct type of its own. For complex types, structs and classes largely side-step the issue of weak typedefs, and in other languages strong typedefs are offered instead of (or in addition to) weak typedefs. In general, code today still uses this latter convention of specifying usage where it remains unclear, but using the hungarian-style prefix has fallen out of fashion -- today you'd more likely see robot.orientation_as_degrees, rather than robot.degreesOrientation.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement