Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Can pure virtual function be called in base class constructor?

Reply
Thread Tools

Can pure virtual function be called in base class constructor?

 
 
PengYu.UT@gmail.com
Guest
Posts: n/a
 
      10-14-2005
Hi,

A pure function is called in the base function constructor. It generate
a run time error: "pure virtual method called".

My problem is that class A have some derived classes. I want A's
constructor change its behaviour accounting to the derived class.

I tried to make A::fun() not pure virtual but virtual. It doesn't
generate any error. But A::fun() is called in A's construction, while I
want B::fun() be called. I just don't want to define a default virtual
function.

I'm wondering if there is any work around to solve this problem.

Best wishes,
Peng


#include <iostream>

class A{
public:
A(){ fun();}
virtual void fun() = 0;
};

class B : public A{
public:
virtual void fun(){
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};

int main(int argc, char *argv[])
{
B b;
}

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      10-14-2005
wrote:
> A pure function is called in the base function constructor. It
> generate a run time error: "pure virtual method called".
>
> My problem is that class A have some derived classes. I want A's
> constructor change its behaviour accounting to the derived class.
>
> I tried to make A::fun() not pure virtual but virtual. It doesn't
> generate any error. But A::fun() is called in A's construction, while
> I want B::fun() be called. I just don't want to define a default
> virtual function.


What you're trying to accomplish goes against a very basic principle:
member functions shall not be called for an object whose construction
hasn't completed. If you're trying to call B::fun from A::A, the B
object hasn't finished constructing. Java is notoriously bad about
this particular behaviour and it is a constant cause of trouble.

> I'm wondering if there is any work around to solve this problem.


A work-around is a separate (maybe virtual) "initialise" member
function, which will be called by the _user_ of your A or B class,
after creating the object. If you want that sequence (construct,
then initialise) to be executed without client's knowing about it,
you need a factory (or several).

V


 
Reply With Quote
 
 
 
 
David White
Guest
Posts: n/a
 
      10-14-2005
wrote:
> Hi,
>
> A pure function is called in the base function constructor. It
> generate a run time error: "pure virtual method called".
>
> My problem is that class A have some derived classes. I want A's
> constructor change its behaviour accounting to the derived class.
>
> I tried to make A::fun() not pure virtual but virtual. It doesn't
> generate any error. But A::fun() is called in A's construction, while
> I want B::fun() be called. I just don't want to define a default
> virtual function.
>
> I'm wondering if there is any work around to solve this problem.


Assuming that you might be constructing any derived class and that you want
to call the most derived class's fun(), and only once, and you want to call
it from a constructor, the following illustrates a (not entirely
satisfactory) workaround:

class A
{
public:
A(int) { /* stuff */ }
virtual void fun() = 0;
};

class B : public A
{
public:
B() { fun();/* other stuff */ }
void fun();
protected:
B(int) { /* other stuff */ }
};

class C : public B
{
public:
C() : B(int) { fun();/* other stuff */ }
void fun();
protected:
C(int) : B(int) { /* other stuff */ }
};

class D : public C
{
public:
D() : C(int) { fun();/* other stuff */ }
void fun();
protected:
D(int) : C(int) { /* other stuff */ }
};

And so on...

DW


 
Reply With Quote
 
David White
Guest
Posts: n/a
 
      10-14-2005
David White wrote:
>
> class A
> {
> public:
> A(int) { /* stuff */ }
> virtual void fun() = 0;
> };


[snip]

Sorry, rushed that a bit. Try this instead:

class A
{
public:
A() { /* stuff */ }
virtual void fun() = 0;
};

class B : public A
{
public:
B() { fun();/* other stuff */ }
void fun();
protected:
B(int) { /* other stuff */ }
};

class C : public B
{
public:
C() : B(0) { fun();/* other stuff */ }
void fun();
protected:
C(int) : B(0) { /* other stuff */ }
};

class D : public C
{
public:
D() : C(0) { fun();/* other stuff */ }
void fun();
protected:
D(int) : C(0) { /* other stuff */ }
};

And so on...

DW


 
Reply With Quote
 
Peter
Guest
Posts: n/a
 
      10-14-2005

wrote:
> Hi,
>
> A pure function is called in the base function constructor. It generate
> a run time error: "pure virtual method called".
>
> My problem is that class A have some derived classes. I want A's
> constructor change its behaviour accounting to the derived class.
>
> I tried to make A::fun() not pure virtual but virtual. It doesn't
> generate any error. But A::fun() is called in A's construction, while I
> want B::fun() be called. I just don't want to define a default virtual
> function.

Yes, if you try to call B::fun(), you should define a explicit
constructor to invoke it. Since class B like you've wrote has no
constructor, compiler will sythesize a default construtor to invoke
A:A() for you. that wouldn't invoke B:fun() at all. Doing that is your
responsibility not compiler.
> I'm wondering if there is any work around to solve this problem.
>
> Best wishes,
> Peng
>
>
> #include <iostream>
>
> class A{
> public:
> A(){ fun();}
> virtual void fun() = 0;
> };
>
> class B : public A{
> public:
> virtual void fun(){
> std::cout << __PRETTY_FUNCTION__ << std::endl;
> }
> };
>
> int main(int argc, char *argv[])
> {
> B b;
> }


 
Reply With Quote
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      10-14-2005
When a well respected expert such as Meyers includes item #9
in his Effectice C++, Third Edition, titled "Never call a virtual
function during construction or destruction", you have to have
to have a very good reasons to do it . That book should be
read by every C++ programmer.

Sutter and Alexandrescu's C++ Coding Standards item #49 gives an
example of how to get around this issue by using an initialize
function.

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-14-2005
* :
>
> My problem is that class A have some derived classes. I want A's
> constructor change its behaviour accounting to the derived class.


That's FAQ item 23.4, e.g. at
<url: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.4>

(I often answer this question because I argued hard to get that into the FAQ,
so it's sort of 50% "my" item even though the wording is Marshall's...)

(But do people point to the FAQ anyway? No, they either don't understand the
problem, perhaps because of hasty reading of the news article, like Peter, or
give for once in a million Bad Advice, like Victor (sorry, but it was really
bad) did this time, it's very rare but happens, also for me, or give bad
advice with an Appeal To Authority fallacy added on top, like the anonymous
AnonMail. I hope people will point more to the FAQ, both because it reduces
discussion that can muddy waters, and because it helps people find the FAQ.)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-14-2005
* Victor Bazarov:
> wrote:
> > A pure function is called in the base function constructor. It
> > generate a run time error: "pure virtual method called".
> >
> > My problem is that class A have some derived classes. I want A's
> > constructor change its behaviour accounting to the derived class.
> >
> > I tried to make A::fun() not pure virtual but virtual. It doesn't
> > generate any error. But A::fun() is called in A's construction, while
> > I want B::fun() be called. I just don't want to define a default
> > virtual function.

>
> What you're trying to accomplish goes against a very basic principle:
> member functions shall not be called for an object whose construction
> hasn't completed. If you're trying to call B::fun from A::A, the B
> object hasn't finished constructing. Java is notoriously bad about
> this particular behaviour and it is a constant cause of trouble.
>
> > I'm wondering if there is any work around to solve this problem.

>
> A work-around is a separate (maybe virtual) "initialise" member
> function, which will be called by the _user_ of your A or B class,
> after creating the object.


Don't do that: it allows for zombie objects, double init and whatnot.

See FAQ item 23.4.


> If you want that sequence (construct,
> then initialise) to be executed without client's knowing about it,
> you need a factory (or several).


Nope.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      10-18-2005
In message <>, Alf P. Steinbach
<> writes
>* :
>>
>> My problem is that class A have some derived classes. I want A's
>> constructor change its behaviour accounting to the derived class.

>
>That's FAQ item 23.4, e.g. at
><url: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.4>


You mean the item that's moved to 23.5 (and 23.6) ?

http://www.parashift.com/c++-faq-lit....html#faq-23.5
http://www.parashift.com/c++-faq-lit....html#faq-23.6
>
>(I often answer this question because I argued hard to get that into the FAQ,
>so it's sort of 50% "my" item even though the wording is Marshall's...)
>
>(But do people point to the FAQ anyway? No, they either don't understand the
>problem, perhaps because of hasty reading of the news article, like Peter, or
>give for once in a million Bad Advice, like Victor (sorry, but it was really
>bad) did this time, it's very rare but happens, also for me, or give bad
>advice with an Appeal To Authority fallacy added on top, like the anonymous
>AnonMail.


.... or point to the wrong FAQ ;-(

>I hope people will point more to the FAQ, both because it reduces
>discussion that can muddy waters, and because it helps people find the FAQ.)
>


--
Richard Herring
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-18-2005
* Richard Herring:
> ... or point to the wrong FAQ ;-(


The FAQ numbering changed after my posting. Don't be such a whiner.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Rationale for base class pure virtual function call fromctor/dtor being undefined behaviour. gwowen C++ 6 01-18-2012 07:14 PM
Pure virtual functions: declaring a function in a base class Martin C++ 5 08-26-2010 09:52 AM
Non-template class from a template base class with pure virtual methods vilarneto@gmail.com C++ 2 03-25-2007 08:19 PM
paradox when constructor of an pure abstract base class called? ypjofficial@indiatimes.com C++ 22 01-24-2006 01:41 AM
virtual function and pure virtual function in the implementation of COM IK C++ 2 07-23-2004 02:55 PM



Advertisments