home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,456 of 33,346   
   Leigh Johnston to All   
   Re: Is this correct: virtual method of D   
   05 Jul 12 12:52:32   
   
   From: leigh@i42.co.uk   
      
   On 05/07/2012 18:46, Daniel Krügler wrote:   
   > On 2012-07-05 01:01, Piotr Nycz wrote:   
   >> I know that within constructor of Base class - when calling virtual   
   >> method - the Base method is called, not derived.   
   >>   
   >> I've just wondered what happens if I call virtual method in Derived   
   >> class constructor - but before constructing Base part.  I mean   
   >> calling virtual method to evaluate Base class constructor argument,   
   >> See code:   
   >>   
   >> class Base {   
   >> public:   
   >> Base(const char* name) : name(name) {   
   >> cout << "Base():" << name << endl;   
   >> }   
   >> virtual const char* getName() {   
   >> cout << "Base::getName()" << endl;   
   >> return "Base";   
   >> }   
   >> protected:   
   >> const char* name;   
   >> };   
   >>   
   >> class Derived : public Base {   
   >> public:   
   >> Derived() : Base(getName()) {   
   >> cout << "Derived():" << name << endl;   
   >> }   
   >> virtual const char* getName() {   
   >> cout << "Derived::getName()" << endl;   
   >> return "Derived";   
   >> }   
   >> };   
   >>   
   >> int main() {   
   >> Derived d;   
   >> }   
   >>   
   >> Compiler g++ (4.3.x-4.5x versions) output is:   
   >>   
   >> Derived::getName()   
   >> Base():Derived   
   >> Derived():Derived   
   >>   
   >> However I'd expect:   
   >>   
   >> Base::getName()   
   >> Base():Base   
   >> Derived():Base   
   >   
   > Your expectations are not satisfied according to the standard. The   
   > relevant wording can be found in [class.cdtor] p4:   
   >   
   > "Member functions, including virtual functions (10.3), can be called   
   > during construction or destruction (12.6.2). When a virtual function   
   > is called directly or indirectly from a constructor or from a   
   > destructor, including during the construction or destruction of the   
   > class’s non-static data members, and the object to which the call   
   > applies is the object (call it x) under construction or destruction,   
   > the function called is the final overrider in the constructor’s or   
   > destructor’s class and not one overriding it in a more-derived   
   > class. [..]"   
      
   Not true; this is undefined behaviour; you cannot call a non-static   
   member function of Derived from Derived ctor init-list as there is no   
   no Derived object constructed at that point (there isn't even a Base   
   object constructed at that point).   
      
   > In your example, "the final overrider in the constructor’s or   
   > destructor’s class" is Derived::getName(), not Base::getName().   
   >   
   >> I take into consideration a possibility that g++ does not call   
   >> virtual methods "virtually" in constructors - so I am forcing to   
   >> call virtually by using extra function which calls by base   
   >> pointer. And it produces Segmentation Fault:   
   >>   
   >> const char* virtualGetName(Base* basePtr)   
   >> {   
   >> return basePtr->getName();   
   >> }   
   >>   
   >> class Derived : public Base {   
   >> public:   
   >> Derived() : Base(virtualGetName(this)) {   
   >> cout << "Derived():" << name << endl;   
   >> }   
   >> virtual const char* getName() {   
   >> cout << "Derived::getName()" << endl;   
   >> return "Derived";   
   >> }   
   >> };   
   >   
   > This is undefined behaviour, see below.   
   >   
   >> Please answer: Is this correct, this g++ behavior? What C++   
   >> standard says about that? Maybe it is undefined behavior?   
   >   
   > The first example was well-defined, the second call is undefined   
   > behaviour because you are violating [class.cdtor] p3:   
      
   The first example is undefined behaviour.   
      
   /Leigh   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca