Virtual function call from constructor

Discussion in 'Java' started by Jeff Higgins, Jun 23, 2007.

  1. Jeff Higgins

    Jeff Higgins Guest

    This prints AB?

    public class Test
    {
    Test()
    {
    foo();
    }

    static void foo()
    {
    System.out.print("A");
    }

    public static void main(String[] args)
    {
    Test t = new Test2();
    }

    static class Test2 extends Test
    {
    Test2()
    {
    super();
    foo();
    }

    static void foo()
    {
    System.out.print("B");
    }
    }
    }
    Jeff Higgins, Jun 23, 2007
    #1
    1. Advertising

  2. Jeff Higgins

    Eric Sosman Guest

    Daniel Kraft wrote:
    > Hi all,
    >
    > I came across some unexpected behaviour in Java: When I call a
    > member-function from a class' constructor, this call is done virtual as
    > usual calling the overridden method of the subclass.
    >
    > This seems to me a bit problematic, as it calls a member-function of the
    > subclass which is not yet constructed and might therefore be well in an
    > inconsistent state. One can even call an abstract function from a
    > class' constructor.


    ... which is why every Java text warns you: "Don't Do That."

    > In C++, this is the other way round, there a constructor never calls an
    > overridden method from a subclass, so this inconsitent state can never
    > occur, which seems to me to be the better way. Calling a pure virtual
    > function from a constructor yields at least a warning and of course a
    > linker-error later on.
    >
    > Is there any rationale behind this as it is done in Java? The only
    > reason I can think of is to handle function call's in constructors the
    > same way as it is done with ordinary calls. But the function to call
    > there is would be known at compile-time, so it shouldn't be really hard
    > to implement C++'s behaviour.


    Suppose the class has a non-overridable method (private, final,
    or static) that performs some useful operation on an object. And
    suppose this method uses overridable methods of the object. Do
    you need to compile two variants of this method to make it behave
    differently depending on whether there is or isn't a constructor
    somewhere in its call stack? (In fact, "a constructor" isn't
    enough, not even "a constructor of the same class." If I've got
    a fully-constructed object A lying around and I call a method on
    it while constructing another object B, I want that method to obey
    the overrides when applied to object A but not to B. I'm not sure
    it's even possible to sort that out entirely at compile time. I
    think you'd need a "construction finished" flag on every object --
    in fact, one such flag for every level of inheritance starting
    from Object itself. "Don't Do That" seems a lot simpler ...)

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 23, 2007
    #2
    1. Advertising

  3. Jeff Higgins

    Eric Sosman Guest

    Daniel Kraft wrote:
    >> Suppose the class has a non-overridable method (private, final,
    >> or static) that performs some useful operation on an object. And
    >> suppose this method uses overridable methods of the object. Do
    >> you need to compile two variants of this method to make it behave
    >> differently depending on whether there is or isn't a constructor
    >> somewhere in its call stack? (In fact, "a constructor" isn't
    >> enough, not even "a constructor of the same class." If I've got
    >> a fully-constructed object A lying around and I call a method on
    >> it while constructing another object B, I want that method to obey
    >> the overrides when applied to object A but not to B. I'm not sure
    >> it's even possible to sort that out entirely at compile time. I
    >> think you'd need a "construction finished" flag on every object --
    >> in fact, one such flag for every level of inheritance starting
    >> from Object itself. "Don't Do That" seems a lot simpler ...)

    >
    > Hm, that's a good point! I believe in C++ this is done by updating the
    > vtable for each constructor finished or something like this -- that
    > should also be fairly simple to implement and you do not need a
    > "construction finished" flag, but of couse it imposes some costs.


    I don't know how C++ is implemented, but if the "vtable"
    is a bunch of pointers to methods it sounds like you'd need a
    per-instance edition of it to reflect the instance's fully-
    or partially-constructed state. Sounds like a lot of bloat ...

    > "Don't do it" is of course nice, but precisly it should mean "only call
    > private, final and static methods from a constructor and only if they
    > themselves obey this rule", right?


    Right.

    > But in this case, wouldn't a compile-time waring be useful telling me
    > I'm calling an overridable method from my constructor or the like?


    I suppose so, but I don't think the compiler would be able
    to detect every path that could lead to a Don't Do That call.
    Some of them might not originate in the constructor at all: for
    example, the constructor might insert the half-baked object in
    a collection where another thread could find it before the
    constructor has finished its job.

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 23, 2007
    #3
  4. Jeff Higgins

    Daniel Kraft Guest

    Hi all,

    I came across some unexpected behaviour in Java: When I call a
    member-function from a class' constructor, this call is done virtual as
    usual calling the overridden method of the subclass.

    This seems to me a bit problematic, as it calls a member-function of the
    subclass which is not yet constructed and might therefore be well in an
    inconsistent state. One can even call an abstract function from a
    class' constructor.

    In C++, this is the other way round, there a constructor never calls an
    overridden method from a subclass, so this inconsitent state can never
    occur, which seems to me to be the better way. Calling a pure virtual
    function from a constructor yields at least a warning and of course a
    linker-error later on.

    Is there any rationale behind this as it is done in Java? The only
    reason I can think of is to handle function call's in constructors the
    same way as it is done with ordinary calls. But the function to call
    there is would be known at compile-time, so it shouldn't be really hard
    to implement C++'s behaviour.

    Or is this even considered "a feature"? However, I believe a function
    should *never* be called on an unconstructed object except in the
    constructor of the class itself where the programmer must take care this
    call is valid there.

    Cheers,
    Daniel

    ******************************
    Test.java

    public class Test
    {

    public Test()
    {
    foo();
    }

    public void foo()
    {
    System.out.println("A");
    }

    public static void main(String[] args)
    {
    Test t=new Test2();
    }

    public static class Test2 extends Test
    {

    public Test2()
    {
    super();
    foo();
    }

    public void foo()
    {
    System.out.println("B");
    }

    }

    }

    This produces:
    B
    B

    ********************************
    Test.cpp

    #include <iostream>
    using namespace std;

    class Test
    {
    public:
    Test()
    {
    foo();
    }
    virtual void foo()
    {
    cout << "A" << endl;
    }
    };

    class Test2 : public Test
    {
    public:
    Test2()
    : Test()
    {
    foo();
    }
    virtual void foo()
    {
    cout << "B" << endl;
    }
    };

    int main()
    {
    Test* t(new Test2());
    delete t;
    return 0;
    }

    This produces:
    A
    B

    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress --
    so please use good, old E-MAIL!
    Daniel Kraft, Jun 23, 2007
    #4
  5. Jeff Higgins

    Daniel Kraft Guest

    Jeff Higgins wrote:
    > This prints AB?


    Try it out, for me it does.

    > public class Test
    > {
    > Test()
    > {
    > foo();
    > }
    >
    > static void foo()
    > {
    > System.out.print("A");
    > }
    >
    > public static void main(String[] args)
    > {
    > Test t = new Test2();
    > }
    >
    > static class Test2 extends Test
    > {
    > Test2()
    > {
    > super();
    > foo();
    > }
    >
    > static void foo()
    > {
    > System.out.print("B");
    > }
    > }
    > }
    >
    >



    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress --
    so please use good, old E-MAIL!
    Daniel Kraft, Jun 23, 2007
    #5
  6. Jeff Higgins

    Roedy Green Guest

    On Sat, 23 Jun 2007 13:35:18 +0000, Daniel Kraft <> wrote,
    quoted or indirectly quoted someone who said :

    >This seems to me a bit problematic, as it calls a member-function of the
    >subclass which is not yet constructed and might therefore be well in an
    >inconsistent state. One can even call an abstract function from a
    >class' constructor.


    You can get uninitialised variables and other weirdness. Generally
    don't do it. Avoid calling virtual functions in constructors.

    see http://mindprod.com/jgloss/constructor.html point #10.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Jun 23, 2007
    #6
  7. Jeff Higgins

    Daniel Kraft Guest

    > Suppose the class has a non-overridable method (private, final,
    > or static) that performs some useful operation on an object. And
    > suppose this method uses overridable methods of the object. Do
    > you need to compile two variants of this method to make it behave
    > differently depending on whether there is or isn't a constructor
    > somewhere in its call stack? (In fact, "a constructor" isn't
    > enough, not even "a constructor of the same class." If I've got
    > a fully-constructed object A lying around and I call a method on
    > it while constructing another object B, I want that method to obey
    > the overrides when applied to object A but not to B. I'm not sure
    > it's even possible to sort that out entirely at compile time. I
    > think you'd need a "construction finished" flag on every object --
    > in fact, one such flag for every level of inheritance starting
    > from Object itself. "Don't Do That" seems a lot simpler ...)


    Hm, that's a good point! I believe in C++ this is done by updating the
    vtable for each constructor finished or something like this -- that
    should also be fairly simple to implement and you do not need a
    "construction finished" flag, but of couse it imposes some costs.

    "Don't do it" is of course nice, but precisly it should mean "only call
    private, final and static methods from a constructor and only if they
    themselves obey this rule", right?

    But in this case, wouldn't a compile-time waring be useful telling me
    I'm calling an overridable method from my constructor or the like?

    Yours,
    Daniel

    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress --
    so please use good, old E-MAIL!
    Daniel Kraft, Jun 23, 2007
    #7
  8. Jeff Higgins

    Lew Guest

    Daniel Kraft wrote:
    > Right, the vtable (or virtual table) is a table of function pointers
    > stored within each object so the overridden method is found. But I
    > really believe this is there in Java, too, but in Java of course the
    > fact of methods being virtual is "hidden" to the programmer.
    >
    > So yes, this is some bloat, but AFAIK this bloat is really necessary for
    > polymorphism with virtual methods. And unlike Java, in C++ you do not
    > have to keep a pointer there for *every* method a class has, only to
    > those which you really intend to be overridden and used polymorphistic...


    So don't use Java, then. Do your work in C++.

    What do you mean by "you ... have to keep a pointer"? Are you certain that
    Java doesn't inline non-polymorphic methods, or even polymorphic ones? How is
    "keeping a pointer" less worthy than not doing so? In any event, vtable or
    not, threaded or pointer, has literally nothing to do with Java semantics,
    which are defined irrespective of their implementation.

    It seems to me that the illogic of a method only being polymorphic outside a
    constructor but, inconsistently, not inside it, trumps the apparent illogic
    but actual good sense of polymorphic (or otherwise) methods only seeing
    fully-constructed objects after they're fully constructed.

    --
    Lew
    Lew, Jun 23, 2007
    #8
  9. Jeff Higgins

    Daniel Kraft Guest

    Eric Sosman wrote:
    >> Hm, that's a good point! I believe in C++ this is done by updating
    >> the vtable for each constructor finished or something like this --
    >> that should also be fairly simple to implement and you do not need a
    >> "construction finished" flag, but of couse it imposes some costs.

    >
    > I don't know how C++ is implemented, but if the "vtable"
    > is a bunch of pointers to methods it sounds like you'd need a
    > per-instance edition of it to reflect the instance's fully-
    > or partially-constructed state. Sounds like a lot of bloat ...


    Right, the vtable (or virtual table) is a table of function pointers
    stored within each object so the overridden method is found. But I
    really believe this is there in Java, too, but in Java of course the
    fact of methods being virtual is "hidden" to the programmer.

    So yes, this is some bloat, but AFAIK this bloat is really necessary for
    polymorphism with virtual methods. And unlike Java, in C++ you do not
    have to keep a pointer there for *every* method a class has, only to
    those which you really intend to be overridden and used polymorphistic...

    Cheers,
    Daniel

    --
    Got two Dear-Daniel-Instant Messages
    by MSN, associate ICQ with stress --
    so please use good, old E-MAIL!
    Daniel Kraft, Jun 23, 2007
    #9
  10. "Eric Sosman" <> wrote in message
    news:...
    > Daniel Kraft wrote:
    >>> Suppose the class has a non-overridable method (private, final,
    >>> or static) that performs some useful operation on an object. And
    >>> suppose this method uses overridable methods of the object. Do
    >>> you need to compile two variants of this method to make it behave
    >>> differently depending on whether there is or isn't a constructor
    >>> somewhere in its call stack? (In fact, "a constructor" isn't
    >>> enough, not even "a constructor of the same class." If I've got
    >>> a fully-constructed object A lying around and I call a method on
    >>> it while constructing another object B, I want that method to obey
    >>> the overrides when applied to object A but not to B. I'm not sure
    >>> it's even possible to sort that out entirely at compile time. I
    >>> think you'd need a "construction finished" flag on every object --
    >>> in fact, one such flag for every level of inheritance starting
    >>> from Object itself. "Don't Do That" seems a lot simpler ...)

    >>
    >> Hm, that's a good point! I believe in C++ this is done by updating the
    >> vtable for each constructor finished or something like this -- that
    >> should also be fairly simple to implement and you do not need a
    >> "construction finished" flag, but of couse it imposes some costs.


    You are correct.
    >
    > I don't know how C++ is implemented, but if the "vtable"
    > is a bunch of pointers to methods it sounds like you'd need a
    > per-instance edition of it to reflect the instance's fully-
    > or partially-constructed state. Sounds like a lot of bloat ...


    Not per-instance, per-class. Assume S2 extends S1, and S1 extends S0. An
    Sn constructor:

    calls the superclass constructor (if there is a superclass)
    points its vtable at the Sn version
    runs its code

    The result is that the constructor runs as if the object were the type being
    constructed, and when all have run, the object is of the correct
    (most-derived) type. No bloat involved. I always find it silly when people
    who know nothing about a language assume that if it does things differently
    from the languages they're used to, it must be stupid and inefficient to do
    so.

    Calling virtual methods (directly or indirectly) in a constructor is
    problematical. C++ tries to solve it by limiting the way they're called.
    Java makes avoiding problems wholly the programmer's responsibility.
    Neither is stupid or inefficient; both have advantages and disadvantages.
    (Ironically, the difference is opposite to the usual one, since C++ is being
    nannyish and Java is giving you all the rope you want.)
    Mike Schilling, Jun 24, 2007
    #10
  11. "Daniel Kraft" <> wrote in message
    news:f5j9fk$6hp$...
    ....
    >
    > Right, the vtable (or virtual table) is a table of function pointers
    > stored within each object so the overridden method is found. But I really
    > believe this is there in Java, too, but in Java of course the fact of
    > methods being virtual is "hidden" to the programmer.


    Not at all. In Java, private methods aren't virtual and all other methods
    are, and this is understood by every competent Java programmer. And the
    vtable in C++ is part of the implementation: it's not something the
    programmer can access [1], and thus is equally "hidden".
    >
    > So yes, this is some bloat,


    No, there isn't. See my explanation upthread.

    >but AFAIK this bloat is really necessary for polymorphism with virtual
    >methods. And unlike Java, in C++ you do not have to keep a pointer there
    >for *every* method a class has, only to those which you really intend to be
    >overridden and used polymorphistic..


    The inner workings of the JVM are very hidden. There's no reason to think
    that if a method is never overridden that the JVM can't dispatch to a
    method directly.

    1. OK, you can access it using casts and pointer arithmetic, in an
    implementation-specific way. I've done this, and even for good reasons.
    But it's not part of the language definition.
    Mike Schilling, Jun 24, 2007
    #11
  12. Jeff Higgins

    Twisted Guest

    On Jun 23, 10:33 am, Daniel Kraft <> wrote:
    > "Don't do it" is of course nice, but precisly it should mean "only call
    > private, final and static methods from a constructor and only if they
    > themselves obey this rule", right?


    Basically. I'd divide my methods into "those that can definitely cope
    with an incompletely-constructed Foo" and "all the others". The latter
    including all methods not in Foo, including in Foo's superclass but
    not overridden by Foo, or overridable by Foo's subclasses. So the
    first set is already limited to a subset of the final, static, and
    private methods of Foo. Lastly, the rule I'd have is for the
    constructor *never to pass "this" to a method not in the first
    subset*, and to exclude a method from that subset if it ever passes
    "this" to a method outside the subset.

    This includes the implicit "this" argument passed when invoking a
    member, of course.

    The rule that results is "only call private, final and static methods
    from a constructor and only if they themselves obey this rule" with
    the additional restriction that this additionally applies to methods
    of ANY class receiving an explicit argument of "this".

    In fact, javac complains in some cases about passing "this" as an
    argument to a method call from a constructor, which helps avoid some
    bad potential problems.
    Twisted, Jun 24, 2007
    #12
  13. Jeff Higgins

    Eric Sosman Guest

    Mike Schilling wrote:
    > "Eric Sosman" <> wrote in message
    > news:...
    >> Daniel Kraft wrote:
    >>>> Suppose the class has a non-overridable method (private, final,
    >>>> or static) that performs some useful operation on an object. And
    >>>> suppose this method uses overridable methods of the object. Do
    >>>> you need to compile two variants of this method to make it behave
    >>>> differently depending on whether there is or isn't a constructor
    >>>> somewhere in its call stack? (In fact, "a constructor" isn't
    >>>> enough, not even "a constructor of the same class." If I've got
    >>>> a fully-constructed object A lying around and I call a method on
    >>>> it while constructing another object B, I want that method to obey
    >>>> the overrides when applied to object A but not to B. I'm not sure
    >>>> it's even possible to sort that out entirely at compile time. I
    >>>> think you'd need a "construction finished" flag on every object --
    >>>> in fact, one such flag for every level of inheritance starting
    >>>> from Object itself. "Don't Do That" seems a lot simpler ...)
    >>> Hm, that's a good point! I believe in C++ this is done by updating the
    >>> vtable for each constructor finished or something like this -- that
    >>> should also be fairly simple to implement and you do not need a
    >>> "construction finished" flag, but of couse it imposes some costs.

    >
    > You are correct.
    >> I don't know how C++ is implemented, but if the "vtable"
    >> is a bunch of pointers to methods it sounds like you'd need a
    >> per-instance edition of it to reflect the instance's fully-
    >> or partially-constructed state. Sounds like a lot of bloat ...

    >
    > Not per-instance, per-class. Assume S2 extends S1, and S1 extends S0. An
    > Sn constructor:
    >
    > calls the superclass constructor (if there is a superclass)
    > points its vtable at the Sn version
    > runs its code
    >
    > The result is that the constructor runs as if the object were the type being
    > constructed, and when all have run, the object is of the correct
    > (most-derived) type. No bloat involved. I always find it silly when people
    > who know nothing about a language assume that if it does things differently
    > from the languages they're used to, it must be stupid and inefficient to do
    > so.


    Somehow I'm failing to find the word "stupid" or "inefficient"
    in anything that I wrote. Could you help me with my proofreading,
    please?

    I *did* use the word "bloat," and it still seems justifiable.
    The implementation you describe (if I've understood you correctly)
    requires each instance to carry a pointer per inheritance level;
    that's certainly larger than the one bit per level I described as
    a hypothetical implementation, and that in turn is larger than
    no per-instance "construction status" at all.

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 24, 2007
    #13
  14. "Eric Sosman" <> wrote in message
    news:...

    >
    > I *did* use the word "bloat," and it still seems justifiable.
    > The implementation you describe (if I've understood you correctly)
    > requires each instance to carry a pointer per inheritance level;
    > that's certainly larger than the one bit per level I described as
    > a hypothetical implementation, and that in turn is larger than
    > no per-instance "construction status" at all.


    Not at all. It requires each instance to hold one pointer, period. The
    *value* of this pointer is changed during construction.
    Mike Schilling, Jun 24, 2007
    #14
  15. Jeff Higgins

    Eric Sosman Guest

    Mike Schilling wrote:
    > "Eric Sosman" <> wrote in message
    > news:...
    >
    >> I *did* use the word "bloat," and it still seems justifiable.
    >> The implementation you describe (if I've understood you correctly)
    >> requires each instance to carry a pointer per inheritance level;
    >> that's certainly larger than the one bit per level I described as
    >> a hypothetical implementation, and that in turn is larger than
    >> no per-instance "construction status" at all.

    >
    > Not at all. It requires each instance to hold one pointer, period. The
    > *value* of this pointer is changed during construction.


    Aha! So if you've got a class that's N levels deep in the
    inheritance hierarchy, you've got N+1 versions of the vtable,
    each corresponding to a different amount of progress through
    the constructor chain. Is that it?

    Hmmm... If that's the way it works, then defining an Nth
    level class really defines N+1 distinct classes, in the sense
    that a class is the set of its behaviors. If applied to an
    object in the midst of construction, which of those N+1 classes
    should getClass() return? And how should instanceof behave?

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 24, 2007
    #15
  16. "Eric Sosman" <> wrote in message
    news:...
    > Mike Schilling wrote:
    >> "Eric Sosman" <> wrote in message
    >> news:...
    >>
    >>> I *did* use the word "bloat," and it still seems justifiable.
    >>> The implementation you describe (if I've understood you correctly)
    >>> requires each instance to carry a pointer per inheritance level;
    >>> that's certainly larger than the one bit per level I described as
    >>> a hypothetical implementation, and that in turn is larger than
    >>> no per-instance "construction status" at all.

    >>
    >> Not at all. It requires each instance to hold one pointer, period. The
    >> *value* of this pointer is changed during construction.

    >
    > Aha! So if you've got a class that's N levels deep in the
    > inheritance hierarchy, you've got N+1 versions of the vtable,
    > each corresponding to a different amount of progress through
    > the constructor chain. Is that it?


    Each class that contains virtual functions defines a vtable. Each instance
    of one of these classes contains one pointer, which points to its class's
    vtable. So an instance of String points to String's vtable, an instance of
    Thread points to Thread's vtable,etc. So far, just as you'd expect. If you
    replace "vtable" by "Class object" and observe that all Java classes contain
    virtual functions (the ones they inherit from Object, at least), exactly
    like Java.

    What C++ does differently is this: During construction, the value of that
    vtable pointer can changes. It will always point to the vtable for the
    class that defines the constructor. So (to use a Java-like example, for
    familiarity), when a PrintStream is being constructed, it does something
    ,like this:

    Point to Object vtable
    Run Object constructor
    Point to OutputStream vtable
    Run OutputStream constructor
    Point to FilterOutputStream vtable
    Run FilterOutputStream constructor
    Point to PrintStream vtable
    Run PrintStream constructor

    At the end of this, the vtable is (correctly) left pointing to the
    PrintStream vtable, which it keeps for the rest of its left. It's possible
    that the reverse process happens during destruction, but I can't say for
    sure. If so, it would be nicely symmetrical.


    >
    > Hmmm... If that's the way it works, then defining an Nth
    > level class really defines N+1 distinct classes, in the sense
    > that a class is the set of its behaviors.


    Not really, because the superclasses already exist. You're defining only
    one new class.

    > If applied to an
    > object in the midst of construction, which of those N+1 classes
    > should getClass() return? And how should instanceof behave?


    C++ doesn't have either of those per se. It does have some limited
    reflection, for instance the <dynamic_cast> operator, which does a similar
    job to instanceof, which I presume would base the current type of the
    object on the current vtable, so that, in effect,

    x instanceof PrintStream

    would be false during the running of the FilterOutputStream constructor.
    Which makes a certain amount of sense: none of the PrintStream fields have
    been initialized, nor are PrintStream-specific methods available.

    Think of it this way. When the Object constructor is running, the instance
    *is* an Object. It may have some extra space allocated at the end, but no
    one can make any use of it. Now, when the OutputStream constructor is
    running, the instance *is* an OutputStream. It may have some extra space
    allocated at the end, but no one can make any use of it. etc. Finally, when
    the PrintStream constructor runs, it *is* a PrintStream.
    Mike Schilling, Jun 24, 2007
    #16
  17. Jeff Higgins

    Twisted Guest

    On Jun 24, 6:02 pm, "Mike Schilling" <>
    wrote:
    > What C++ does differently is this: During construction, the value of that
    > vtable pointer can changes. It will always point to the vtable for the
    > class that defines the constructor.


    Think of it this way: while a Java object is whatever run-time type it
    is for its whole lifetime, a C++ object actually evolves; its run-time
    type is Base during the Base constructor, then Derived when the
    Derived constructor is running. Its run-time type is whatever is fully-
    constructed so far.

    > > Hmmm... If that's the way it works, then defining an Nth
    > > level class really defines N+1 distinct classes, in the sense
    > > that a class is the set of its behaviors.

    >
    > Not really, because the superclasses already exist. You're defining only
    > one new class.


    For example with Base and Derived, there may be a trivial vtable and
    there will be ones for Base and Derived. But the one for Base is used
    not only for incomplete Deriveds, but for other subclasses and vanilla
    Bases as well.

    > C++ doesn't have either of those per se. It does have some limited
    > reflection, for instance the <dynamic_cast> operator, which does a similar
    > job to instanceof...


    Actually, it does the exact same job as a Java cast as in "(String)
    myMap.get(key)" (a common case, pre-Java 5). It gives you a reference
    of the desired compile-time type if the run-time type is assignable to
    that compile-type type, and throws an exception if it isn't so
    assignable. In Java the exception is a ClassCastException; in C++ it's
    something else (bad_cast?) (C++ also has bad_alloc, analogous to
    OutOfMemoryError, and some other exceptions that closely map onto Java
    ones.)

    > which I presume would base the current type of the
    > object on the current vtable, so that, in effect,
    >
    > x instanceof PrintStream
    >
    > would be false during the running of the FilterOutputStream constructor.
    > Which makes a certain amount of sense: none of the PrintStream fields have
    > been initialized, nor are PrintStream-specific methods available.


    I think there may be an RTTI (run-time type identification) ability
    more like instanceof than dynamic_cast; I'm not sure if it treats
    objects' run-time types as evolving during construction, though it
    seems likely. Dynamic dispatch certainly does, regardless.

    > Think of it this way. When the Object constructor is running, the instance
    > *is* an Object. It may have some extra space allocated at the end, but no
    > one can make any use of it. Now, when the OutputStream constructor is
    > running, the instance *is* an OutputStream. It may have some extra space
    > allocated at the end, but no one can make any use of it. etc. Finally, when
    > the PrintStream constructor runs, it *is* a PrintStream.


    Except that in Java it's a PrintStream from the outset, and is not a
    vanilla Object even when Object's constructor is not finished yet.
    (Does Object even have a nontrivial constructor?) This only applies to
    their C++ analogues in the iostreams library. :)
    Twisted, Jun 24, 2007
    #17
  18. "Twisted" <> wrote in message
    news:...

    >
    >> Think of it this way. When the Object constructor is running, the
    >> instance
    >> *is* an Object. It may have some extra space allocated at the end, but
    >> no
    >> one can make any use of it. Now, when the OutputStream constructor is
    >> running, the instance *is* an OutputStream. It may have some extra space
    >> allocated at the end, but no one can make any use of it. etc. Finally,
    >> when
    >> the PrintStream constructor runs, it *is* a PrintStream.

    >
    > Except that in Java it's a PrintStream from the outset, and is not a
    > vanilla Object even when Object's constructor is not finished yet.
    > (Does Object even have a nontrivial constructor?)


    That's presumably a JVM-specific question.

    > This only applies to
    > their C++ analogues in the iostreams library. :)


    Yes, I was probably unclear. I was trying to describe the C++ mechanism,
    but using a Java class hierarchy as an example (since there wasn't a C++
    hierarchy handy.)
    Mike Schilling, Jun 24, 2007
    #18
  19. Jeff Higgins

    Twisted Guest

    On Jun 24, 6:57 pm, "Mike Schilling" <>
    wrote:
    > > Except that in Java it's a PrintStream from the outset, and is not a
    > > vanilla Object even when Object's constructor is not finished yet.
    > > (Does Object even have a nontrivial constructor?)

    >
    > That's presumably a JVM-specific question.


    Yes. I expect a JVM and a corresponding implementation of at least the
    java.lang portion of the standard library to be fairly tightly
    coupled; probably why they are bundled and transported about as a
    single entity, a JRE. Certainly some System stuff, Object.wait/notify,
    and the stuff in java.lang.ref will be tightly coupled to the VM
    implementation in various ways, and likely also String interning.
    Class/ClassLoader and reflection too, and now probably
    java.util.concurrency (and that one doesn't even start with
    java.lang).

    > > This only applies to
    > > their C++ analogues in the iostreams library. :)

    >
    > Yes, I was probably unclear. I was trying to describe the C++ mechanism,
    > but using a Java class hierarchy as an example (since there wasn't a C++
    > hierarchy handy.)


    I figured as much, but also figured it might not be clear to every
    reader. Having similar stuff expressed in other words as well will
    probably make it much more reliably understood by this thread's
    readers.
    Twisted, Jun 25, 2007
    #19
  20. Jeff Higgins

    Eric Sosman Guest

    Mike Schilling wrote:
    > "Twisted" <> wrote in message
    > news:...
    >
    >>> Think of it this way. When the Object constructor is running, the
    >>> instance
    >>> *is* an Object. It may have some extra space allocated at the end, but
    >>> no
    >>> one can make any use of it. Now, when the OutputStream constructor is
    >>> running, the instance *is* an OutputStream. It may have some extra space
    >>> allocated at the end, but no one can make any use of it. etc. Finally,
    >>> when
    >>> the PrintStream constructor runs, it *is* a PrintStream.

    >> Except that in Java it's a PrintStream from the outset, and is not a
    >> vanilla Object even when Object's constructor is not finished yet.
    >> (Does Object even have a nontrivial constructor?)

    >
    > That's presumably a JVM-specific question.


    No; that's the Java language. If Object's constructor
    ultimately chained from a PrintStream constructor were to
    evaluate `this instanceof PrintStream' the result would be
    `true', on every JVM. (Object's constructor has no reason
    to do any such thing, but that's another matter.)

    You can test the pattern with

    class Super {
    Super() {
    System.out.println((this instanceof Super)
    + ", " + (this instanceof Sub));
    }
    public static void main(String[] unused) {
    new Super();
    new Sub();
    }
    }
    class Sub extends Super {
    }

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 25, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt Graham
    Replies:
    3
    Views:
    499
    Matt Graham
    Feb 7, 2004
  2. IK
    Replies:
    2
    Views:
    590
    hemraj
    Jul 23, 2004
  3. archimed7592
    Replies:
    4
    Views:
    728
    =?UTF-8?B?UGF3ZcWC?=
    May 30, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,190
  5. Replies:
    25
    Views:
    975
    Ian Collins
    Feb 24, 2008
Loading...

Share This Page