BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

'Pure-virtual-function-called'-error-problem

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++)
View previous topic :: View next topic  
Author Message
M_R
Guest





PostPosted: Tue Jun 28, 2005 10:59 am    Post subject: 'Pure-virtual-function-called'-error-problem Reply with quote



When trying to get an instance of an inherited class I get a
pure-virtual-function-called-error.

The problem is that the inherited constructor first calls the
basic-class constructor, which by itself should call a virtual methode
f of the inherited class.

Unfortunately this last is not the cass. Even if f is declared as
virtual in the base-class, it is tried to call the base class's
methode f.

Did I make some kind of obvious error?

Or Is this standard-behaviour? It would make some kind of sensel,
because the current object is not yet ready-constructed. But the data
the inherited class will deliver in this function are already created:
thy return values of static's in this class.

So, how can I convince the compiler to call the inherited method
instead?

Thanks a lot,

Michael
Back to top
Hendrik Schober
Guest





PostPosted: Tue Jun 28, 2005 11:10 am    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote



M_R <M_R> wrote:
Quote:
[attempt to call a virtual function from ctor]

A constructor (ctor) turns raw memory into
an object. A destructor (dtor) turns an
object back into raw memory.
A base class ctor is invoked /before/ the
derived class' ctor. (This is so that within
the drived class' ctor the base class' part
of the object is already constructed and
reliably usable.) One consequence of this is
that, when the base class' ctor is called,
there is no derived object yet. What will
later make up the part of the derived object
is still raw memory at this time. So you
cannot call a function of the derived class
-- there is no object for which to call it.
This is why, in a class' ctor, the object's
dynamic type is of the class where the ctor
belongs to and all virtual function calls
resolve to the functions in this class.
(The same holds true for the dtor, BTW. It
is called /after/ the derived class' dtor,
so at this time there is no derived object
anymore.)

What you need is usually known as "two-phase
construction". There is no such thing in C++.
However, there are several ways to workaround
this limitation. If you post your problem
here, someone might be able to suggest one.

Quote:
Thanks a lot,

Michael


Schobi

--
[email]SpamTrap (AT) gmx (DOT) de[/email] is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett



Back to top
M_R
Guest





PostPosted: Tue Jun 28, 2005 2:25 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote



"Hendrik Schober" <SpamTrap (AT) gmx (DOT) de> schrieb:

Thanks for your explaining answers.

Quote:
M_R <M_R> wrote:
It would make some kind of sensel,
because the current object is not yet ready-constructed.

Seems I' ve got the right thoughts about that

Quote:
However, there are several ways to workaround
this limitation. If you post your problem
here, someone might be able to suggest one.

Instead of doing the initializings inside the base-class-constructor,
I defined an Init()-methode in the base class (and also an UnInit())
and called the Init() at the beginning of the constructor in the
inherited class (and the UnInit() at the end of the destructor of the
inherited class). This works fine: the virtual methods of the
inherited classes are called...

Thanks,

Michael

Back to top
Hendrik Schober
Guest





PostPosted: Tue Jun 28, 2005 2:40 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote

M_R <M_R> wrote:
Quote:
"Hendrik Schober" <SpamTrap (AT) gmx (DOT) de> schrieb:

Thanks for your explaining answers.

M_R <M_R> wrote:
It would make some kind of sensel,
because the current object is not yet ready-constructed.

Seems I' ve got the right thoughts about that

However, there are several ways to workaround
this limitation. If you post your problem
here, someone might be able to suggest one.

Instead of doing the initializings inside the base-class-constructor,
I defined an Init()-methode in the base class (and also an UnInit())
and called the Init() at the beginning of the constructor in the
inherited class (and the UnInit() at the end of the destructor of the
inherited class). This works fine: the virtual methods of the
inherited classes are called...

...as long as you don't inherit from this
class. A common way to do two-stage init is
to do it by wrapping the implementation:

class XYZ {
private:
class XYZImpl_ {
public:
XYZImpl_();
~XYZImpl_();
init();
deinit();
};
XYZImpl_ impl_;
public:
XYZ() : impl_() {impl_.init();}
~XYZ() {impl_.deinit();}
};

This way users of 'XYZ' aren't bothered with
calling '[de]init()' (and thus won't forget
it). Consider making 'impl_' a pointer using
the pimpl idiom to completely hide 'XYZImpl_'
from users.

Quote:
Thanks,

Michael


Schobi

--
[email]SpamTrap (AT) gmx (DOT) de[/email] is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett



Back to top
Chris Uzdavinis (TeamB)
Guest





PostPosted: Tue Jun 28, 2005 3:06 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote

M_R <> writes:

Quote:
When trying to get an instance of an inherited class I get a
pure-virtual-function-called-error.

The problem is that the inherited constructor first calls the
basic-class constructor, which by itself should call a virtual methode
f of the inherited class.

Unfortunately this last is not the cass. Even if f is declared as
virtual in the base-class, it is tried to call the base class's
methode f.

Did I make some kind of obvious error?

Yes, you cannot call pure virtual functions from constructors or
destructors. The resulting behavior is undefined.

You can explicitly call a base class function through qualification.

basename::function()

(Assuming it's implemented in the base.)

--
Chris (TeamB);

Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Jun 28, 2005 5:05 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote


<M_R> wrote


Quote:
The problem is that the inherited constructor first calls
the basic-class constructor, which by itself should call
a virtual methode f of the inherited class.

You cannot do that. The derived class does not exist yet when the base
class constructor is running. There is no way to call a virtual method in a
base class constructor and have a derived method be called. You will have
to change your class base design to do something else.

Quote:
Even if f is declared as virtual in the base-class, it is tried
to call the base class's methode f.

As well it should.

Quote:
Did I make some kind of obvious error?

Yes. Your class design is wrong. Your base class constructor has a
requirement that cannot be satisfied.

Quote:
Or Is this standard-behaviour?

Yes.

Quote:
It would make some kind of sensel, because the current object
is not yet ready-constructed. But the data the inherited class
will deliver in this function are already created: thy return values
of static's in this class.

The only way I know of to let the base class constructor gain access to that
data is to either:

1) pass the data as parameters to the constructor, ie:

class Base
{
public:
Base(parameters)
{
// do something with the parameters...
}
};

class Derived : public Base
{
public:
Derived()
: Base(YourData)
{
}
};

2) template the base class, pass the derived class type as the template
parameter, and then call the static methods from that class type.

template<class T>
class Base
{
public:
Base()
{
DataType data = T::GetData();
// use data as needed...
}
};

class Derived : public Base<Derived>
{
public:
Derived()
: Base()
{
}

static DataType GetData()
{
return YourData;
}
};

Quote:
So, how can I convince the compiler to call the inherited
method instead?

You cannot. Not via virtuals, anyway.


Gambit



Back to top
Chris Uzdavinis (TeamB)
Guest





PostPosted: Tue Jun 28, 2005 5:21 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> writes:

Quote:
The only way I know of to let the base class constructor gain access to that
data is to either:

1) pass the data as parameters to the constructor, ie:

class Base
{
public:
Base(parameters)
{
// do something with the parameters...
}
};

class Derived : public Base
{
public:
Derived()
: Base(YourData)
{
}
};

It may be worth noting that "YourData" must not be non-static member
data of Derived or the behavior is undefined.



Quote:
2) template the base class, pass the derived class type as the template
parameter, and then call the static methods from that class type.

template class Base
{
public:
Base()
{
DataType data = T::GetData();
// use data as needed...
}
};

class Derived : public Base {
public:
Derived()
: Base()
{
}

static DataType GetData()
{
return YourData;
}
};

If it's static data, this is fine, though it may be easier for Derived
to simply pass the data to the base and avoid templates, like in your
first example. If you have to use a default constructor, then the
template trick is a viable solution.

--
Chris (TeamB);

Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Jun 28, 2005 8:34 pm    Post subject: Re: 'Pure-virtual-function-called'-error-problem Reply with quote


"Chris Uzdavinis (TeamB)" <chris (AT) uzdavinis (DOT) com> wrote


Quote:
It may be worth noting that "YourData" must not be non-static
member data of Derived or the behavior is undefined.

True. But since M_R said that the data was already available before the
derived object is ready, and that static methods are used to retreive the
data, this is not likely to be an issue in this particular situation.


Gambit



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.