Straight from the source

Straight from the source

  • Comments 7

One of the truly great things about working here is that Distinguished Engineers take time out of their busy schedules to answer random questions. Many thanks to Anders and Scott for sharing their insights.

Incidentally, as I've mentioned before, I'll sometimes ask interview candidates how good a C++ programmer they are on a scale from one to ten.  If they say "nine", I'll ask them the kind of question that I asked Scott and see what they say.

(And yes, I was for many years known as "that guy who's always wearing the Tilley hat".  I still have many Tilleys at home, but I usually only wear them when I'm sailing now.)

  • Note that your question itself makes an incorrect statement:

    "... initializing derived class members using constructor arguments before base class constructors run (which seems good, and is what C++ does)."

    C++ does not do it this way. In C++, base class constructors run first, then non-static data members are initialized, and finally the constructor body runs. See C++ standard 12.6.2/5
  • Correct. I was unclear on what I meant there. What I intended to get across was that C++ provides the syntax

    class foo : public bar {
    int x;
    foo(int y) : x(y)

    to initialize the member in the derived class. But, as you correctly note, the base class constructor is going to run before the initializer.

    What I should have said is "C++ solves this problem by restricting virtual function calls to the most-constructed-so-far type. If we want to have C# objects always act as though they are their most derived type, we could solve this problem by using the C++ syntax for initializing derived class members before the base class constructor is called."

    See, it strikes me as odd that you can initialize a derived class member like this:

    class foo {
    int x = 123;
    foo() : base() {

    and the initialization happens before the base constructor, but there's no way to do this:

    foo(int y) : x = y , base() {

    Sorry for the unclarity.
  • Stan Lipmann's take on this is also quite interesting:
    http://blogs.msdn.com/slippman/archive/2004/01/28/63917.aspx

    with a followup:
    http://blogs.msdn.com/slippman/archive/2004/01/30/65056.aspx
  • http://images.google.com/images?q=tilley%20hat
  • That's the one. My Tilley of choice is the T3G -- the one with the green underbrim and aussie-style snap-up sides.
  • IIRC, in C++ the scope resolution operator (::) can be used to specifiy precisely which class' implementation of a virtual method one wishes to invoke. This is real handy:
    class Base
    {
    virtual void Foo();
    void Bar() { Base::Foo(); }
    };

    If Bar() assumes the implementation of Foo() by Base, it can force that implementation to be used. It's easy to imagine scenarios where a design like this can be confusing, however it's also easy to imagine scenarios like this where it is legitimate.

    Besides, good documentation practice would dictate that if Bar() assumed a particular implementation of Foo(), it would say so in the form of a method invariant. In this case, derived objects might be clever enough to maintain the invariant like so:
    class Derived : public Base
    {
    virtual void Foo() { Base::Foo(); ...}
    };
    If this convention were adopted, Base::Bar() would not need to use the scope resolution operator. Clearly this design is restricted to scenarios where Derived::Foo() and Base::Foo() will not interact inappropriately.

    Frankly, I don't know if C# provides similar functionality. If it doesn't, I can't help but wonder why, since it is not a feature that can be used "on accident," and it allows the developer to maintain access to code that has already been written (and thus preserves the principle of code reuse). Lastly, it allows developers to specify precisely which implementation they require, which allows invariants to be maintained.

    It is also interesting to consider the question from the perspective of state transitions. Assuming no side-effecting methods, an object method either queries the state of the object, or it is intended to move the object into a new state. By convention, method naming indicates which state the object is supposed to transition into. Polymorphism complicates this model when base classes use polymorphic helper methods to alter their own state. This presents some interesting problems in terms of dependability, but this post is long enough without analyzing the implications of dynamic binding.
  • In relation to Scott's blog about calling a virtual function from a constructor, this tactic doesn't seem like a good idea, but we were considering it as a solution to the following problem:

    We have a DataSet with Table Adapters built for MSAccess using OLEDB. We are using Visual Studio 2005 and .Net 2.0.

    When the designer creates insert, update and delete queries it encloses the table name and field names with a ` (ASCII char 96).

    For example:

    INSERT INTO `table` (`col1`, `col2`, `col3`) values (....)

    Is there a reason for this character? Assuming it's for escape purposes, is there a setting to make Visual Studio use another character, eg "[" or "]"?

    We were planning on creating a parent to the table adapters in the dataset. The parent would have a virtual function "initialize" that would strip away or replace these characters from the commandText.

    But I would rather avoid all of this, if VS has a setting...

Page 1 of 1 (7 items)