Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Base constructor calling with parameter that will be constructed in the derived constructor

QUESTION 1)

class Base {
    Base(std::string name);

    virtual std::string generateName();
}

class Derived : Base {
    Derived();

    virtual std::string generateName();
}

here comes the question :

what method will be called on generateName() ?

Derived :: Derived : Base(generateName()) {
    //what method will be called on generateName() ? 
}

QUESTION 2)

how should i make it? if the default constructor must accept a parameter, but i need to generate that parameter in the Derived constructor?

like image 602
Peter Lapisu Avatar asked Jan 26 '11 12:01

Peter Lapisu


2 Answers

First, the solution: use a static member function or a nonmember function.

As for the behavior, Derived::generateName() will be called. The long sentence in the C++ Standard that defines this behavior says (C++03 12.7/3):

When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor's own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor's class, or overriding it in one of the other base classes of the most derived object.

Because the constructor being executed at the time of the virtual call is the Derived constructor, Derived::generateName() is called.

A now-deleted answer rightly referred to an article by Scott Meyers that recommends "Never Call Virtual Functions during Construction or Destruction." The rules for what overrider gets called are complex and difficult to remember.

like image 196
James McNellis Avatar answered Sep 21 '22 09:09

James McNellis


Take two...

I did a run with calls to generateName() in the base class initialiser and both constructors. The output left me nonplussed:

Derived (called from Derived's Base initializer)
Base    (called from Base ctor)
Derived (called from Derived ctor)

I never imagined that a class could morph from being a derived to a base, then back to a derived in a single construction sequence. You learn something new every day.

like image 30
Marcelo Cantos Avatar answered Sep 22 '22 09:09

Marcelo Cantos