In reading through Scott Meyers book, Effective C++, his expression that it should actually be viewed as a federation of languages, is actually a great way to look at it. He describes it in terms of C++ the C, Object-Oriented, Template, and STL groups (I would’ve skipped the STL) is fairly accurate.
The true gem however, I think is Item 19: Treat class design as type design. This IMHO, is more true in languages like C++, Java, and C#, than what some folks are accustomed to. You’re playing with the type system, so act like it.
He points out 12 issues involved with developing a new type or ‘class’, I’ll summarize them briefly:
- How should objects of your new type be created & destroyed?
- How should initialization differ from assignment?
- How should passing-by-value work with your type?
- What restrictions are their on legal values for your new type?
- How does inheritance effect your new type?
- What kind of type conversions should be allowed?
- What operators and functions make sense on it?
- What standard functions should be disallowed?
- Who should have access to its members?
- What kind of guarantees does it make?
- How general is it?
- Is a new type really what you need?
If anything, I would say rip out those pages of the book, and make it a required `check list` of ground new programmers must cover before they are allowed to add a new type to the code base. The book gives excellent explanation of each point, so I won’t offer much deep exposition here on them: I’ve just tried to condense them. (Buy or borrow the book lol.)
If you’re going to be creating a new type; which you are effectively doing when creating a new class in C++, then these issues all apply to you. I would argue, that most of this applies to any language with user defined types and operator overloading; which is also most main stream language supporting OOP.
Points 2, 3, 4, 6, 7, and to an extent 8, all make sense in the domain of creating a new ‘type’. Personally, I tend to skip much of it unless for example, overloading certain operators offers serious savings on expressiveness, or the default copy constructor / assignment operators are insufficient. These points that the book outlines, really are the source of most complexity in developing C++ classes, perhaps because like C-strings and good ol’ malloc(), it exposes a lower level picture of things to the programmer. Everyone can program in C, but not everyone should.
Points 1, 5, and 9, are more unique to designing a class than the others are, at first glance. Simply put you can’t create a class without taking 1 and 5 into consideration, it’s just required. Although admittedly you can skimp a little on 5 in some cases but probably shouldn’t. If you know jack about OOP, let along designing software, you know the answer to 9 is the minimalist level of access required. I actually enjoy that Scott Meyers work demonstrates, that OOP goes a lot further than the class keyword! Abstraction, encapsulation, and modularity are an integral part of doing quality work, and object oriented programming is but a useful paradigm for modeling that, especially when polymorphic inheritance is applicable. Point 5 becomes a bit easier to live with as time goes on, although I still suggest favouring object composition over inheritance when a class hierarchy isn’t the most appropriate thing for solving the problem at hand (and minimizing the ruddy singletons).
Points 10, 11, and 12 are true of most elements of composition within a program: from even for functions. Those kind issues get easier with experience, assuming you learned a slugs worth about software design in the first place. Some people never learn it, period.
Why based on those oh so true points, would I conclude that C++ is a failure? Because the “Average” slep is just not competent enough to deal with most of it as often as necessary. Heck, I still encounter code bases where the programmer can’t tell the fucking difference between signed and unsigned integers when designing their interface. There are some truly brilliant programmers out there, and many of them do use C++ quite heavily, but in the wider majority, as with most majorities: you’ll find more Homer J. Simpson’s than Sir Isaac Newtons in the crowd. This goes for just about every thing on earth :'(. We could use some more clones of Newton and a few less Apple and Fig Newtons walking around. So long as the average is sufficiently uneducated, and still allowed to (ab)use the language, I think it’s a failure; but hey, who ever said C++ was designed with the incompetent people in mind ;).
It is simply to much for the average Tom, Dick, and Harry to be able to consider it. Not that those proverbial average three bozos should be screwing with a complex system… half as often as they are found to be. Maybe I’m more inclined to make such statements, as I still know average adults who can’t understand a + b = b + a; yet, and I have met a whole lotta stupid people: without even counting programmers.
disclaimer: I drew this conclusion ages ago after reading EC++s item 19, that “C++ is a failure”, and was in a more stable state of mind at the time then the one used to finally type this out.