csua.org/u/ec6 -> groups.google.com/groups?selm=CLINE.94Jul12094407%40cheetah.clarkson.edu&oe=utf-8&output=gplain
A: Life as we know it suddenly comes to a catastrophic end. It is the programmer's --not the compiler's-- responsibility to get the connection between new and delete correct. If you get it wrong, neither a compile-time nor a run-time error message will be generated by the compiler. A: Constructors (ctors) do not return any values, so no returned error code is possible. The best way to handle failure is therefore to throw' an exception. If your compiler doesn't yet support exceptions, several possibilities remain. The simplest is to put the object itself into a half baked' state by setting an internal status bit. Naturally there should be a query (inspector') method to check this bit, allowing clients to discover whether they have a live object. Other member functions should check this bit, and either do a no-op (or perhaps something more obnoxious such as abort()') if the object isn't really alive. Check out how the iostreams package handles attempts to open nonexistent/illegal files for an example of prior art. A: This will NOT work, since comments are parsed before the macro is expanded: #ifdef DEBUG_ON #define DBG #else #define DBG // #endif DBG cout << foo; A: A program is const correct' if it never mutates a constant object. A: Declaring the constness' of a parameter is just another form of type safety. It is almost as if a constant String, for example, lost' its various mutative operations. If you find type safety helps you get systems correct (especially large systems), you'll find const correctness helps also. A: Type safety requires you to annotate your code with type information. In theory, expressing this type information isn't necessary -- witness untyped languages as an example of this. However in practice, programmers often know in their heads a lot of interesting information about their code, so type safety (and, by extension, const correctness) merely provide structured ways to get this information into their keyboards. Every const' you add over here' requires you to add four more over there'. The snowball effect is magnificent -- unless you have to pay for it. Long about the middle of the process, someone stumbles on a function that needs to be const but can't be const, and then they know why their system wasn't functioning correctly all along. This is the benefit of const correctness, but it should be installed from the beginning. A: A const member function is a promise to the caller not to change the object. Put the word const' after the member function's signature; C++ compilers aren't allowed to assume the bitwise const, since a non-const alias could exist which could modify the state of the object (gluing a const' ptr to an object doesn't promise the object won't change; I talked to Jonathan Shopiro at the C++AtWork conference, and he confirmed that the above view has been ratified by the ANSI-C++ standards board. This doesn't make it a perfect' view, but it will make it the standard' view. These different categories of member fns are distinguished by whether the member fn is const' or not. A: In current C++, const member fns are allowed to cast away the const-ness of the "this" ptr'. Programmers use (some say misuse') this to tickle internally used counters, cache values, or some other non-client-visible change. Since C++ allows you to use const member fns to indicate the abstract/meaning-wise state of the object doesn't change (as opposed to the concrete/bit-wise state), the meaning' of the object shouldn't change during a const member fn. Those who believe const' member fns shouldn't be allowed to change the bits of the struct itself call the abstract const' view Humpty Dumpty const' (Humpty Dumpty said that words mean what he wants them to mean). The response is that a class' public interface *should* mean exactly what the class designer wants it to mean, in Humpty Dumpty's words, nothing more and nothing less'. If the class designer says that accessing the length of a List doesn't change the List, then one can access the length of a const' List (even though the len()' member fn may internally cache the length for future accesses). Some proposals are before the ANSI/ISO C++ standards bodies to provide syntax that allows individual data members to be designated as can be modified in a const member fn' using a prefix such as const'. This would blend the best of the give the compiler a chance to cache data across a const member fn', but only if aliasing can be solved (see next question). A: If the object is constructed in the scope of the const member fn invocation, and if all the non-const member function invocations between the object's construction and the const member fn invocation are statically bound, and if every one of these invocations is also inline'd, and if the ctor itself is inline', and if any member fns the ctor calls are inline, then the answer is Yes, the soon-to-be-standard interpretation of the language would prohibit a very smart compiler from detecting the above scenario, and the register cache would be unnecessarily flushed'. The reader should judge whether the above scenario is common enough to warrant a language change which would break existing code. A: Inheritance is what separates abstract data type (ADT) programming from OOP. In fact, everything discussed so far could be simulated in your garden variety ADT programming language (ex: Ada, Modula-2, C with a little work , etc). Inheritance and the consequent (subclass) polymorphism are the two big additions which separate a language like Ada from an object-oriented programming language. A: Human beings abstract things on two dimensions: part-of and kind-of. We say that a Ford Taurus is-a-kind-of-a Car, and that a Ford Taurus has parts such as Engine, Tire, etc. The part-of hierarchy has been a first class part of software since the ADT style became relevant, but programmers have had to whip up their own customized techniques for simulating kind-of (usually in an ad hoc manner). An example of kind-of decomposition', consider the genus/species biology charts. Knowing the internal parts of various fauna and flora is important for certain applications, but knowing the groupings (kinds, categories) is equally important. A: In addition to being an abstraction mechanism that makes is-a-kind-of relationships explicit, inheritance can also be used as a means of incremental programming'. A derived class inherits all the representation (bits) of its base class, plus all the base class' mechanism (code). Another device (virtual functions, described below) allows derived classes to selectively override some or all of the base class' mechanism (replace and/or enhance the various algorithms). This simple ability is surprisingly powerful: it effectively adds a third dimension' to programming. After becoming fluent in C++, most programmers find languages like C and Ada to be flat' (a cute little book, Flatland', aptly describes those living in a two dimensional plane, and their disbelief about a strange third dimension that is somehow neither North, South, East nor West, but is Up'). As a trivial example, suppose you have a Linked List that is too slow, and you wish to cache its length. You could open up' the List class' (or module'), and modify it directly (which would certainly be appropriate for such a simple situation), but suppose the List's physical size is critical, and some important client cannot afford to add the extra machine word to every List. Another option would be to textually copy the List module and modify the copy, but this increases the amount of code that must be maintained, and also presumes you have access to the internal source code of the List module. The OO solution is to realize that a List that caches its length is-a-kind-of-a List, so we inherit: class FastList : public List { public: //override operations so the cache stays hot' protected: int length; A: The short answer: yes -- you don't even need the cast'. Long answer: a derived class is a specialized version of the base class (Derived is-a-kind-of-a Base'). The upward conversion is perfectly safe, and happens all the time (a ptr to a Derived is in fact pointing to a sp...
|