Re: Rationale for base class pure virtual function call from ctor/dtor being undefined behaviour.
"Leigh Johnston" <leigh@i42.co.uk> wrote in message
news:tfydnWenHpz4z4nSnZ2dnUVZ8hidnZ2d@giganews.com...
On 16/01/2012 16:14, Paul <pchrist wrote:
"Leigh Johnston"<leigh@i42.co.uk> wrote in message
news:dZmdnf_yLtEuronSnZ2dnUVZ8nydnZ2d@giganews.com...
On 16/01/2012 14:14, Paul<pchrist wrote:
"Leigh Johnston"<leigh@i42.co.uk> wrote in message
news:KuednRghMrM8gInSnZ2dnUVZ8uadnZ2d@giganews.com...
On 16/01/2012 12:04, Paul<pchrist wrote:
[snip]
http://www.artima.com/cppsource/nevercall.html
That is just one opinion; another opinion is that calling virtual
functions from ctors and dtors is OK as long as you are aware that the
object is an instance of the base type when still in base ctor or
dtor.
Remember the abstract class cannot exist as an object so there is no
object
on which to invoke a member function. A non-static member function
needs
to
be invoked on an object.
Of course there is an object; a partially constructed object to be
precise. When in a base class ctor the object is currently an instance
of
the base class type and whether or not the class is abstract has no
bearing on this fact.
You are viewing the partially constructed object as an instance of the
abstract base object.
That is what the effective type of the partially constructed object is
whilst it is in the base class ctor; a class invariant can be said to
start in the body of a ctor and this is true for base classes as well as
derived classes irrespective of the presence of virtual functions (pure or
not).
But this goes against the concept of not being able to instanciate an
abstract class type.
No it doesn't.
A pure virtual function is intended as an interface that will (must) be
implemented in a non abstract derived class.
If you want to call Base::foo during construction you could do the
following:
<code ref="how it is">
class Base{
public:
Base(){std::cout<<"Base constructor...\n"; }
virtual void foo()=0;
};
void Base::foo(){std::cout<<"Base foo...\n";}
class Derived : public Base{
public:
Derived(){ std::cout<<"Derived constructor...\n"; Base::foo(); }
void foo(){std::cout<<"Derived foo...\n";}
};
int main(){
Derived d;
Base* bp = &d;
bp->foo();
}
</code>
The PVF must be implemented by the derived class and not by the base class.
If para 6 of 10.4 did not exist this would not be the case. This case you
propose is:
<code ref="how you think it should be">
class Base{
public:
Base(){std::cout<<"Base constructor...\n"; foo();}/*UB*/
virtual void foo()=0;
};
void Base::foo(){std::cout<<"Base foo...\n";}
class Derived : public Base{
public:
Derived(){ std::cout<<"Derived constructor...\n";}
void foo(){std::cout<<"Derived foo...\n";}
};
int main(){
Derived d;
Base* bp = &d;
bp->foo();
}
</code>
If this were allowed then we no longer have a situation where the derived
class has full control over the implementation of the PVF. Here we have one
version of foo invoked during object construction of which the derived class
has no control over its implementation.
Basically the PVF is no longer just an Interface if you allow this
behaviour.
--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---