Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Programming IT Technology

Where Should You Apply Various C++ Coding Practices? 37

Dr. Love asks: "C++ contains a mountain of features. I am searching for a good C++ coding practice - what language features to avoid, what language features to make extensive use of, etc. In my survey of C++ coding practices, there seems to be a plethora of philosophies ranging from the stingy to the highly abstracted and elaborate. By stingy, I'm referring to those that use few of C++'s advanced features, such as Mozilla. At the opposite end of the spectrum, there are elaborate practices that make extensive use of the STL, exceptions, RTTI, templates, etc. Those who prefer the simple implementations tend to argue that elaborate practices result in inefficient, unclear, and unportable code. Those who prefer the elaborate implementations tend to argue that simple implementations are missing out on a Nirvana of reuse and clean design. Are these arguments unfounded? What has been your experience with C++ coding guidelines? What does the industry expect?" Just like the choice of the language itself, the choice of the features you use in your language should lend itself to the task you are developing. Some projects don't need to use every single feature of C++ to get the job done, however use of those ignored features in other projects might make your life (and your code) much easier to handle.
This discussion has been archived. No new comments can be posted.

Where Should You Apply Certain C++ Coding Practices?

Comments Filter:
  • Hey, there are libraries that manage to avoid C++ constructs to abstract this sort of stuff. For example, B-tree operators could use a fixed structure in which there exists the data fields necessary for the library to do its thing, and the "payload" of the structure is a void pointer to the data referenced by the B-tree node. This means that you can have disk-resident B-trees by using the void pointer to refer instead to a byte offset; array-resident B-trees by using the void pointer to hold an index; value-oriented B-trees by having an integer value in the void pointer.

    Oh, I know that you can duplicate most (or all) OO features in straight C. I've just run into the limits of practicality for this on a few occasions. At least twice I've caught myself implementing collections of function pointers in structures to emulate polymorphism. If I'm doing *that*, I might as well just use C++ and save myself a lot of hassles debugging typos.

    YMMV. I realize that for some applications, having to trust automatic implementation is bad, but for most of what I work with it's worth it.
  • by Christopher Thomas ( 11717 ) on Saturday April 14, 2001 @10:23AM (#291928)
    The feature that crops up in practice most for me is polymorphism.

    I code mainly in C, not C++. I've just written yet another program that uses a binary tree to store several different types of data. The naive way of writing this is to make several different tree-node types and several sets of nearly-identical tree manipulation functions. The way I did it was to kludge things with a data type identifier and a union of the possible data stored.

    The Right Way to implement this is to make an abstract class for the tree node, write the tree manipulation methods to work with the abstract class, and make derived classes that store different types of data, with appropriate constructors that initialize the data fields. Anything that doesn't have to care about the data type can just manipulate the objects as the original abstract class.

    This situation has cropped up before. Any situation where I'm doing the same type of thing with many types of data can benefit from derived classes and polymorpism. This happens frequently with utility libraries that I write, but also crops up now and then with certain types of information storage task.

    I still code in C most of the time, because I'm too lazy to dust off my C++ books and these are just my own projects. However, this is indeed a common set of cases where features of C++ would be useful.
  • NuMega's BoundsChecker [numega.com] is a program that can discover memory leaks in your program. I think it's only for NT.
  • I think there are always exceptions to any generalizations.

    For instance, operator overloading. The std use it to make std::vector behave and look like an array. So you have something like
    std::vector<int> v; int i = v[4];
    Looks natural to me.

    Nice thing about the stream I/O is that you don't have to deal with the damn %s%d%S crap. Sorry, printf is just evil compared to cout.

    References, mostly agree, but you can save some time and memory by using reference in connection with const for objects. For instance,
    int foo( const Obj& o );
    Instead of making a copy of Obj, you know get a reference to the original object. Saves you time.

  • It sounds like you're looking for either Smalltalk or Objective-C. Check them out.
  • Templates, at least as implemented by the various C++ compilers I've worked with, are a portability nightmare. Yes, type-safe collections would be nice, but if there has to be a choice between collections of Object (only) and C++-style templates, I'll take Java. Really portable templates would be nice, and then the collections API could be redone.

    Your comments about destructors and const goes to your last point. You're right, if you try to program Java as you do C++ you're hosed. I realize that Java and C++ are quite different (even ignoring memory management). My main point is that if I had to code in C++ again, I'd throw out the things that Java threw out.

  • by geophile ( 16995 ) <(jao) (at) (geophile.com)> on Sunday April 15, 2001 @11:36AM (#291933) Homepage
    I did C++ for many years and I'm now much happier in Java. I have thought about what C++ features I'd use and not use if I had to go back, and I think I'd restrict myself to the Java subset. So I'd include polymorphism, single inheritance and access control (private, protected public). I'd throw out pointer arithmetic, operator overloading, and templates. I might even avoid embedded objects (e.g. class A { B b; };). Maybe use a limited form of multiple inheritance, simulating Java interfaces.

    I really think that Java got it right.

  • C++ is a "batteries not included" language: like C, but unlike Python or Java, its standard libraries are really quite small. For instance, despite the existence of the STL and C++'s powerful templates, there's not even an official, standard hashtable class (though most folks ship a vendor-specific or something of the sort). That said, library design was a MAJOR concern in the creation of C++, so it's possible to build some great stuff (look at Qt, which I think is quite nice). So, one of the big challenges in C++ is to find the right tools on which to base your project. Scott Meyers' "Effective C++" and "More Effective C++" would be pretty high on my list. If you have a great budget, check out Insure++ from www.parasoft.com. It catches MANY MANY common coding and runtime errors and is VERY COOL. Unlike simple bounds checkers, it even flags memory accesses that may be a problem at some point in the future, and it has tools to help you track memory usage over time, measure code coverage, etc. Failing that, you can use the memory checker built into C++ Builder 5 for free (well, free if you own the IDE) if you're on Windows. Also, look at some foundation libraries, if you're serious about building a large system and you don't want to reinvent the wheel. ACE (www.riverace.com) is free/open source and VERY, VERY extensive, but this comes with something of a learning curve. Common C++ (cplusplus.sourceforge.net) looked a bit friendlier last time I checked it out, but it was a little buggy (about a year ago, at least). On the commercial side, Qt is fantastic, and I've heard some decent reviews of Rogue Wave's Tools.h++. A well-designed foundation library will already have worked out a lot of the cross platform/cross compiler issues for you, and that alone can be worth the price of admission. Most of all: good luck! --JRZ
  • by dutky ( 20510 ) on Saturday April 14, 2001 @03:35PM (#291935) Homepage Journal

    The good parts:

    • inheritance: if you're not using this then why bother with C++ at all?
    • class polymorphism: this goes hand in hand with using inheritance.
    • exceptions: even though they aren't supported by many of the low level libraries, they make the code much easier to read.
    • templates: even though the standard isn't entirely reliable on all compilers and they are a bit mystifying to newbies, they fit very well with the OO philosophy.

    The bad parts:

    • overloading: using the familiar language operators to do double (and often tripple) duty is just plain confusing in real code. It looks really cool in language demos, but doesn't work for real world projects. When you include both function overloading and default parameter values, you get an unmanagable mess.
    • stream I/O: for the same reason that operator overloading is a crock, so is stream I/O. I quote "I saw cout shifted "Hello World" times to the left and stopped right there."
    • references: most of your programmer's time will be spent reading the code rather than the class definitions (and this is as it should be) so anything that makes it more difficult to tell what is happening in the code is bad and to be avoided. References are just such a beast, especially when used in parameter lists. (As a return value they are almost acceptable)
  • References, mostly agree, but you can save some time and memory by using reference in connection with const for objects. For instance,
    int foo( const Obj& o );
    Instead of making a copy of Obj, you know get a reference to the original object. Saves you time.

    No kidding. If people would learn how to use const correctly, many many runtime bugs would be caught in the compiler. Also the code is easier to understand if const is used correctly.

    p.s. I happen to think references are very nice.
  • "Look! I learned a new c++ feature today, there has to be some way I can jam this in somewhere in my project."
    Be careful! Don't do it just because it's possible, but for a reason. Focus on the project's task and not the language it is written in.
    Your code might end up like that abc rhyme "the lazy brown fox...", if you think your program will be more complete if every c++ language feature is used.
  • by rjh ( 40933 ) <rjh@sixdemonbag.org> on Saturday April 14, 2001 @01:29PM (#291938)
    C++ is, like Perl, such a mess because the problem set is such a mess. That means it's pretty easy to shoot yourself in the foot--and given C++'s power, shots to the foot often take off everything below your waist.

    If crossplatform, portable code is a necessity, then be very careful when using newer features such as templates. I've had the devil's own time taking code that works perfectly fine in GCC-2.96 (the Red Hat snapshot, which is a very fine C++ compiler), but breaks horribly under GCC-2.91. Code that compiles cleanly under MSVC++ will oftentimes break horribly in GCC-2.96, etc.

    The fewer C++ features you use, the less chance you'll run into these gotchas. That's why the Mozilla team uses a restricted set of C++ functions, I think, far more than to enhance readability or whatnot--the simple fact is, the more C++ features you use, the harder it is to get it to compile under Foo compiler, because Foo doesn't properly implement such-and-such chapters of the Standard; and code written for the Foo compiler breaks on the Bar compiler, because Bar demands strict adherence to the spec, which Foo doesn't provide.

    That being said: give consideration to at least using the inheritance features of C++'s class system. Inheritance is, if anything, the most useful feature of C++, and is well-supported by every compiler. Don't treat C++ like Ada83, where classes existed only to protect data as private and to create interfaces to other bits of functionality; let your C++ classes be hierarchial, let them inherit from base classes, and use that to your advantage.

    After that, I don't have any recommendations. I'm personally a big fan of generic programming (templatized programming) and the STL. The STL is fearsomely efficient and fast. It's got a learning curve like the Matterhorn, but once you climb it, it's wonderful.

    BTW, if anyone tells you to ignore templates on grounds that they cause bloat, please check out the home page of Amit Patel, a Doctoral student at Stanford (who, I believe, often reads Slashdot--if so, hi, Amit, drop me a line sometime) and friend of mine. According to benchmarks he provides on his page (click here [stanford.edu]), templatized code that makes use of the STL is often, if not almost always, of comparable executable size to an equivalent C program, and substantially faster.

    Some compilers, such as Sun's, are absolutely awful with templates--that's probably how the nasty myth of templatized code being bloated and slow came to be. As a rule, though, there's no general truth to this myth; some compilers produce bloated code when using foo, bar and baz parts of the language, but it's not a characteristic of the language--just a characteristic of a crappy compiler.
  • Exceptions are a definite win. The syntax makes good sense and the semantics do pretty much what you would want. (Well, what I would want, anyway.) try, catch, and throw just about eliminate the need for goto or longjmp, and are much prettier besides. They're easy to use right, and it would take a deliberate act to use them wrong.

    Inheritance and polymorphism are good when used judiciously, but can definitely hurt you; spaghetti inheritance [tuxedo.org] is one of the ugliest things around. Each class should abstract some thing or concept in the system; if that's not the case, it's time to start chopping things out of your inheritance hierarchy.

    The STL (and C++ template in general) syntax gives me a headache, personally; good idea, but seems glommed onto the language. Other than the occasional container class, which is simple enough, I avoid it.

    Good question for discussion, by the way!

    Tom Swiss | the infamous tms | http://www.infamous.net/

  • If you want someone to tell you if your code sucks, call the expert. Bjarne Stroustrup's "The C++ Programming Language" should be required reading. He talks about a lot of this stuff, and tells when each C++ feature should and should not be used. Highly recommended.
  • My java lecturer tried to convince me that inheritence was what was to be used in one case where it obviously wasn't. Late in the semester the whole lecture theatre had a good laugh when she wasnt able to change directory in dos to execute javadoc. Pity by that time I had chosen to spend the lecture time somewhere slighty more useful in front of the sun api docs.

    Geez I hate it when people with a science degree with a major in computing try to teach IT, it really doesnt work, at least in my experience.
  • I think instead of trying to use features of a language one should try and recognize design patterns and apply them to your project. Pick up the book "Design Patterns: Elements of Reusable Object Oriented Software" by the GoF. It will be time well spent.
  • It's frighteningly accurate. Where I've seen it happen most is inheritance abuse. Newbie C++ programmers will tend to use inheritance over composition and nothing screams "Newbie C++ programmer" like a horrible inheritance tree that more often than not inherits the same objects further on down the tree. I've seen code (That may well be coming to a device near you soon) where every object inherited from every other object with no clear deliniation of object responsibilites.

    I've heard tell that it takes about a year with the language to get to be a really good C++ programmer. I wonder if that assumes that you have someone who can tell you why your code sucks. If you fall into the bad habits of the newbie programmer and they don't get corrected, I can't see a programmer ever getting better at it.

  • by Greyfox ( 87712 ) on Saturday April 14, 2001 @08:40PM (#291944) Homepage Journal
    There are some things that will bring your coding to the next level. The first and foremost of these is "Design Patterns." Shell out some cash and get the book. It's so worth it it's not even funny.

    Next is the STL. The STL is a fairly recent newcomer to C++ as are templates themselves. The STL can save you a lot of time that you'd spend reimplementing the same data structures. It's an excellent resource. There are other cool things you can do with templates as well -- the GTK-- signal system is way cool, for instance.

    Finally, check out here [get2net.dk] (http://hjem.get2net.dk/nimrod/tipdesign.htm for the goat wary.) It's a bunch of archived articles from the C++ netnews group. There are plenty of good coding practise pointers and code snippets and it's a great resource.

    These three resources should get you well ahead of the curve when it comes to making good use of the C++ features.

  • Usually, the people who shoot themselves in the foot are those that dont care about design. Ive seen projects where people program right from an ER. The fact that Perl and C++ have so many features is irrelevant if youve designed a good system and thought about when and how you are going to use them.
  • Bruce Eckel's books are also pretty good (Thinking in C++ (2nd), also Thinking in (several other languages/ patterns)).


    --
    News for geeks in Austin: www.geekaustin.org [geekaustin.org]
  • I am so not a C++ guru, but I'll try to respond with what I know. (I last used C++ for a class a year ago, of which the major focus was data structures, both the old skool way and with newer features. But I tried to blot out any inadvertantly aquired knowledge after the semester ended with heavy drinking... ;-)

    Ok, so you have a data structure that uses a Node inner class (or whatever it's called in C++). If you template that, would not all be well? So like Tree has a private inner class Node that only Tree's member functions can manipulate. Since presumably Tree would only have one data type per instance (an Int tree or Float tree or Foo Tree :), Tree's constructor can make the Nodes be the right type. getNode and setNode and addNode in Tree would also be template based so they return and accept the right thing(type T; removeNode would probably just be bool anyway). What I'm getting at is that you may not need to make an inheritance chain, just one templated Tree class[1]. This is the point of templates as I recall them (I recall reading an interesting interview with the guy whose name I can't recall at the moment who initiated the STL, wherein he said that he very much does not like traditional "OO" programming in favor of generic, paramerterized/templated, almost functional programming).

    So anyway take all this with a huge grain of salt. :-) I'm far from being an expert (perl and C and Java are more my thing). And thanks for your reply, it made me stretch my head to think about this stuff again, and brain stretching is always cool.

    [1] like the whole Tree class is templated on type T. Then the Node inner class and all the accessor/mutator functions use the same type. So each Tree instance is of a given type. If you wanted a Tree that could hold more than one thing (is that still a tree in the classical sense?), it would get wierd.


    --
    News for geeks in Austin: www.geekaustin.org [geekaustin.org]
  • The Right Way to implement this is to make an abstract class for the tree node, write the tree manipulation methods to work with the abstract class, and make derived classes that store different types of data, with appropriate constructors that initialize the data fields. Anything that doesn't have to care about the data type can just manipulate the objects as the original abstract class.

    This sounds like a perfect place to use the STL and/or C++'s templating mechanism. Trust me, I'm not a huge C++ fan, but the container classes in the STL kick ass (I imagine something like what you describe is already there). Even if the STL don't give you no lovin', templates (and references) make it really easy to write a storage class that works over an arbitrary range of types.

    This is just my 2 cent's worth. I'm mainly a C guy too, but the STL was the single biggest thing tempting me to switch to C++.

    There is good coverage of all this in Bruce Eckel's Thinking in C++ (and other such as the C++ Primer by Lajoie et al.) I mention Bruce Eckel's books because they're available to peruse online, his site is mindview.net which unfortunately seems to be down right now (maybe it's hosted in california ;-). I found a mirror of his C++ books in PDF form here [planetpdf.com] and a mirror of all his books in HTML form here [janiry.com]. If you're like me you'll read the book(s) online and end up liking them so much you want to own a paper copy (and here I make my standard reference to bookpool [bookpool.com] for discount tech books).


    --
    News for geeks in Austin: www.geekaustin.org [geekaustin.org]
  • The Right Way to implement this is to make an abstract class for the tree node, write the tree manipulation methods to work with the abstract class, and make derived classes that store different types of data, with appropriate constructors that initialize the data fields. Anything that doesn't have to care about the data type can just manipulate the objects as the original abstract class.

    This sounds like a perfect place to use the STL and/or C++'s templating mechanism. Trust me, I'm not a huge C++ fan, but the container classes in the STL kick ass (I imagine something like what you describe is already there). Even if the STL don't give you no lovin', templates (and references) make it really easy to write a storage class that works over an arbitrary range of types.

    I'm not following. Here's my problem with that solution:

    Suppose you have a base tree node class that is a protocol class and then you templatize all the derived classes. If you templatize the derived class, nine times out of ten you're going to want to call functions of the derived class using some of the types that the derived class is using. This is impossible if you have a pointer to the base class, since the base class remains blissfully unaware of its derived classes and the types involved with them. If you don't want to call the functions of the derived classes using their types, that's fine, but I don't see that happen in practice that often. Usually when you templatize a class on a type, you are saying "I am class X, and I deal with type T." To speak its language, and call its functions, you usually need to know what type T is.

    Like I said, this is not a problem if you don't have functions in your derived classes that require its caller to know the types being used. If they are all things like "void Execute(void)", then you're good to go. However, if you need to pass a parameter based on the receiver's template type, it seems that a test of the type is in order, which could get messy as more node types are added.

    The other option is to also templatize the base class, but then all your base classes (which, of course, would belong to us) that are templatized on different things have different types, and forming a tree out of them would require bypassing the type system of C++.

    Overall, yes, templates rock. But, like many features of a language, sometimes it doesn't seem to pay to use them.

    Please let me know if I'm missing something.

  • Thanks for clearing that up. I was looking at the problem from a totally different perspective. I was thinking that the desired result was a tree with nodes that had template derived classes, all with different types. But a generic tree that contains only one base type, yea, I could see that. And in that case, I completely agree with you.

  • references: most of your programmer's time will be spent reading the code rather than the class definitions (and this is as it should be) so anything that makes it more difficult to tell what is happening in the code is bad and to be avoided. References are just such a beast, especially when used in parameter lists. (As a return value they are almost acceptable)

    As with all language features, there's a fine line between using and abusing a feature. I see your complaint about references, but the same damage can be done with pointers, and nobody wants to without those (well, not me at least).

    I hate having to think to myself (when dealing with pure C) "Is that struct being passed via a pointer for updating or for efficiency? Which structs being passed are updated?" A simple way to solve the problem: whenever a parameter is passed out of a function via an argument, say so in the code with a comment. Please. Pretty please, even. All it takes is a simple "/* out */" or "// out".

    References don't confuse programmers. Programmers confuse programmers.

  • C++ is, like Perl, such a mess because the problem set is such a mess.

    Not if your are programming applications. C++ is such a mess since it is compatible to C and adds stuff. Also, it carried over all the bad things of C. C was created for low level programming (operating system, drivers etc). Therefore it allowas many things that an application programmer never needs and that hurt, since they are dangerous. IMHO it was one of the bad directions the IT industry took to use C(++) as a standard in almost all software development areas. There are many languages (for ex. Delphi or Eiffel) that have at least as much power for application programming, let you program faster and with less bugs.

    That means it's pretty easy to shoot yourself in the foot--and given C++'s power, shots to the foot often take off everything below your waist.

    Very true. BTW, to the people that say "only WIMPs want safe languages": I prefer to solve a difficult problem with good tools than to be proud to use unnessacarily (sp?) difficult tools and solve an easy problem.
  • Hey, there are libraries that manage to avoid C++ constructs to abstract this sort of stuff. For example, B-tree operators could use a fixed structure in which there exists the data fields necessary for the library to do its thing, and the "payload" of the structure is a void pointer to the data referenced by the B-tree node. This means that you can have disk-resident B-trees by using the void pointer to refer instead to a byte offset; array-resident B-trees by using the void pointer to hold an index; value-oriented B-trees by having an integer value in the void pointer.

    For type purity, you could use an embedded structure definition for the B-tree elements, and the payload would be in the rest of the embedding structure. The B-tree routines would then use appropriate pointers to do its thing.

    As you can probably tell, I tend to think C instead of C++ because most of my programming involves real-time processing. I don't like it when a language does things "behind my back" -- sometimes it's a good thing, sometimes it causes bugs that are impossible to find because of this sort of thing.

    Oh, I don't mind C++ for computational stuff, but it's been so long since I've done something that's "merely" computational that I don't bother to hone the C++ skills I pick up each time I get these rare projects.

    YMMV

  • I Agree, use exceptions. Here is a good text on it: http://www.relisoft.com/book/tech/5resource.html
  • Works in 9x as well
  • If Microsoft's STL is a pain in the ass, use:
    http://www.stlport.org/product.html

    Its free, VERY robust, portable and exception safe.

    Note that in Microsoft's compilers you need to make sure that the "new" operator throws a std::bad_alloc exception instead of returning NULL when memory exhaustion occurs...here is how to:
    http://www.relisoft.com/book/tech/5resource.html
  • by ZeroConcept ( 196261 ) on Sunday April 15, 2001 @03:38PM (#291957)
    My experiences with a 2,000,000 lines of code C++ server project (in winNT):

    1) ALLWAYS use SmartPointers unless you have a compelling reason to not use them.
    2) Memory leaks are going to be your biggest problem, see rule number 1.
    3) Use ASSERT like crazy...everywhere, if you are expecting some valid imput in a method, make sure it's explicilty stated with an ASSERT. ASSERT is the best way to catch an error on the spot.
    4) Make the compiler generate debug symbols in release as a separate file, you WILL find bugs that only happen in RELEASE versions.
    5) Use boundschecker to debug memory problems.
    7) Don't use catch(...) on any other place than your main function...if you need to, rethrow the exception and let the debugger catch it. Never catch an exception that you don't know how to handle on the current scope.
    6) Make your code exception safe, it's the only way to deal with memory exhaustion problems(http://www.relisoft.com/book/tech/5resour ce.html).
    7) If you are using multiple threads and a large number of locks, use smartlocks, otherwise you will have deadlocks (it's painful but does pay off).
    8) If you application is multithreaded, use a static locking order, otherwise you will have deadlocks.
    9) NEVER, NEVER, NEVER create your own collections or strings, use STL.
    10) If you use Visual C++ and STL, make sure you replace the source files with the fixed versions(http://www.dinkumware.com/vc_fixes.html).
    11) Read "Effective C++" and "More effective C++" (look them up in amazon)
    12) Avoid Runtime Type Identification, most of the times you don't need it.

    send me a message at andresmurillo@go.com if you need more info.
  • by bmckeever ( 224043 ) on Sunday April 15, 2001 @12:08PM (#291958)
    It all depends on the team. If everybody on the project is familiar with feature X, then use it where appropriate, even if it's a tricky feature (eg exception handling). If the Right Way calls for a feature that your colleagues understand, then by all means, do it the Right Way. However, the Right Way that leaves the next guy scratching his head is not the true Right Way. On the other hand, I'm not sure it's reasonable for somebody who doesn't have a basic understanding of exceptions and their use (and dangers) to call himself a C++ programmer any longer.

    On the other hand, forbidding a feature (like templates) just because it's complicated can be stupid and self-defeating. Are you really writing your own Map class? Are you sure it's right? What do you do when you need a Map from Foos to Bars, and the only one you have is from Bazes to Quuxes? You don't copy and paste, do you? And your Map doesn't subvert the type system, right? And if you decide you should be using a Set instead of a List, you can fix this with one line of code, right?

  • by bmckeever ( 224043 ) on Sunday April 15, 2001 @12:30PM (#291959)
    A few comments:

    0: You didn't mention the parts that Java got wrong, like the effed-up Collections API (not type-safe), not having deterministic destructors (finally is a clumsy substitute), and not having a const modifier (with semantics different than final).

    1: Why would you throw out templates? They are powerful, and generic code is much better than cut-and-paste programming.

    2: It can be dangerous to think of C++ and Java as being almost the same. Syntactically, they have much in common, which can lull you into thinking they are more similar than they really are. But they are different, and if you regularly switch between them, you can find the gotchas (or they can find you).

  • I met Bruce Eckel at SD98. He was wearing a ringmaster's suit and standing behind a folding table with a guy in a gorilla suit. He was hawking some service, but I can't remember what it was. I did have a good laugh, though.

    I laughed there almost as hard as I did when I saw the Sun Javabean having to be escorted by security guards there to prevent people from tipping it over. Now that was funny.

    Dancin Santa
  • You can find book 1 here [amazon.com].

    And book 2 in the series here [amazon.com].

    And if you're so inclined, the CD can be found here [amazon.com].

    You may be boycotting that site, so check out the following links.

    Book 1 [fatbrain.com]
    Book 2 [fatbrain.com]
    The CD [fatbrain.com]

    Dancin Santa
  • Before you embrace patterns, be aware that they make your program more abstract, sometimes to the point where it's almost impossible to see what's really going on (and where it's going on) without investing a considerable amount of time reading code. See the Apache Xalan library as an example. If you do use patterns, make sure your supporting documentation helps to explain your architecture in real, concrete terms.

    Use C++ for: inheritance, polymorphism, access control (private, protected etc) and exceptions. Ultimately programming is about data structures and algorithms; the rest is sugar.

    Like others who've posted, what I dislike is the amount of stuff C++ does "behind your back". In C this is just about limited to automatic type conversions, which I can cope with.

    I have a feeling that Objective C is probably a cleaner/neater object-oriented C than C++, but maybe that's just wishful thinking (I've only read one or two samples). I'm drifting towards Java now, mostly because of garbage collection but also because the design of the language was partly influenced by a desire to remove the bloat from C++, a sentiment with which I can sympathise.

  • At work, the biggest feature of C++ that we insist that everyone use are exceptions. Using exceptions helps us keep code clean and readable and gets rid of multiple nested if statements everytime we have to test for an error condition. The ability to throw an exception and simply catch them all at the bottom makes debugging a lot simpler.

    Other features that we use include STL, for the simplicity of creating lists and other data structures, and polymorphism. Since our entire project is an object oriented design, we can't get away from it, and in many cases, it greatly reduces the amount of code we have to write and debug.

    That said, however, It is important that you design your object heirarchy and relationships before hand and test to insure that it really will perform the task you intend it to. Otherwise, it turns into an ugly mess.

Love may laugh at locksmiths, but he has a profound respect for money bags. -- Sidney Paternoster, "The Folly of the Wise"

Working...