dpg@extro.ucc.su.OZ.AU (D P Gilbert) (05/14/91)
I was experimenting with polymorphism to see if it works through a function that takes a reference to a base class and got the following surprises. 2 compilers (SUN C++ and Comeau on ix/386) based on cfront 2.0 gave the same results. The following sections in the ARM throw some light on this (but I'm still confused): 4.7 (reference conversion), 5.17 (assignment operator), and 10.2 (Virtual functions). #include <iostream.h> class Base { public: virtual void className() const { cout << "Class name: Base\n"; } }; class D1 : public Base { public: void className() const { cout << "Class name: D1\n"; } }; class D2 : public Base { public: void className() const { cout << "Class name: D2\n"; } }; void test_a(const Base &bas) { bas.className(); } // expect polymorphism void test_b(const Base bas) { bas.className(); } // don't expect ... main() { Base b; D1 d1; D2 d2; Base bb(d2); // Hoped for: cout << "test_a(b) : "; test_a(b); // Class name: Base cout << "test_a(d1) : "; test_a(d1); // Class name: D1 cout << "test_a(bb) : "; test_a(bb); // Class name: Base cout << "test_b(b) : "; test_b(b); // Class name: Base cout << "test_b(d1) : "; test_b(d1); // Class name: Base cout << "test_b(bb) : "; test_b(bb); // Class name: Base } Got the following output: test_a(b) : Class name: Base test_a(d1) : Class name: D1 test_a(bb) : Class name: D2 ??? test_b(b) : Class name: Base test_b(d1) : Class name: D1 ??? test_b(bb) : Class name: D2 ??? These last 2 results seem to indicate I can get polymorphism via base objects? Apologies is this is a stupid question. Thanks Doug Gilbert
jgro@lia (Jeremy Grodberg) (05/15/91)
In article <dpg.674226630@extro> dpg@extro.ucc.su.OZ.AU (D P Gilbert) writes: >I was experimenting with polymorphism to see if it works through a >function that takes a reference to a base class and got the following >surprises. 2 compilers (SUN C++ and Comeau on ix/386) based on cfront >[2.0 gave the same results.] > [ example omitted ] >These last 2 results seem to indicate I can get polymorphism via >base objects? Apologies if this is a stupid question. This is not a stupid question, it is a bug in cfront 2.0. Under certain circumstances (the details of which I do not know), the default copy constructor incorrectly copies over the vtable pointer, giving the new object the wrong virtual functions. I belive this bug does not show up if the object being copied is a different size from the object being copied to, which is why it does not cause a lot of problems in real code (since derived classes almost always add at least one member). The results you expected were in fact the correct results, and the compiler was wrong. -- Jeremy Grodberg "Show me a new widget that's bug-free, and I'll show jgro@lia.com you something that's been through several releases."
mittle@blinn.watson.ibm.com (Josh Mittleman) (05/16/91)
I agree that your results are confusing, and I think that they are simply wrong. I compiled your code with the ATT v2.1 compiler, and I did not reproduce your results. My output was what you expected in the first place: test_a(b) : Class name: Base test_a(d1) : Class name: D1 test_a(bb) : Class name: Base test_b(b) : Class name: Base test_b(d1) : Class name: Base test_b(bb) : Class name: Base It is certainly incorrect to get polymorphism through a base class object, as opposed to through a base class pointer or reference. A Base is a Base, and cannot be anything but a Base. =========================================================================== Josh Mittleman (mittle@watson.ibm.com or joshua@paul.rutgers.edu) J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY 10598
comeau@ditka.Chicago.COM (Greg Comeau) (05/17/91)
In article <dpg.674226630@extro> dpg@extro.ucc.su.OZ.AU (D P Gilbert) writes: >I was experimenting with polymorphism to see if it works through a >function that takes a reference to a base class and got the following >surprises. 2 compilers (SUN C++ and Comeau on ix/386) based on cfront >2.0 gave the same results. Don't be confused. As best I can see that was a bug in cfront 2.0. As 2.1, amongst other things, was a maintenance release, the output you hoped to see is the one properly ported 2.1 cfronts give. - Greg -- Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418 Producers of Comeau C++ 2.1 Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421 Voice:718-945-0009 / Fax:718-441-2310