469,572 Members | 1,343 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,572 developers. It's quick & easy.

Can pure virtual function be called in base class constructor?

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;
}

Oct 14 '05 #1
10 2664
Pe*******@gmail.com 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
Oct 14 '05 #2
Pe*******@gmail.com 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
Oct 14 '05 #3
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
Oct 14 '05 #4

Pe*******@gmail.com 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;
}


Oct 14 '05 #5
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.

Oct 14 '05 #6
* Pe*******@gmail.com:

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?
Oct 14 '05 #7
* Victor Bazarov:
Pe*******@gmail.com 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?
Oct 14 '05 #8
In message <43****************@news.individual.net>, Alf P. Steinbach
<al***@start.no> writes
* Pe*******@gmail.com:

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
Oct 18 '05 #9
* 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?
Oct 18 '05 #10
In message <43***************@news.individual.net>, Alf P. Steinbach
<al***@start.no> writes
* Richard Herring:
... or point to the wrong FAQ ;-(


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

OK, I'll leave that to everyone you've contradicted in this thread ;-)

--
Richard Herring
Oct 18 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by cppaddict | last post: by
11 posts views Thread by santosh | last post: by
37 posts views Thread by WittyGuy | last post: by
10 posts views Thread by Martin Vorbrodt | last post: by
6 posts views Thread by pakis | last post: by
21 posts views Thread by sks | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.