calling pure virtual in abstract class's constructor

V

vsgdp

I have an abstract class A:

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

class B : public A
{
public:
void f() {...}
};

B b;

However, the compiler does not like me calling f in the constructor of A.
But this seems like it should be okay since A is pure virtual, f will be
given in derived classes and exist.
 
A

Axter

vsgdp said:
I have an abstract class A:

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

class B : public A
{
public:
void f() {...}
};

B b;

However, the compiler does not like me calling f in the constructor of A.
But this seems like it should be okay since A is pure virtual, f will be
given in derived classes and exist.

This is not OK, because when you're inside constructor A, B has not
been constructed yet. So you can't call on something that doesn't
exist yet.
Remember, that constructor A, gets constructed before constructor B.
That means any functions in class B, is not avialable to constructor A.
 
I

Ian

vsgdp said:
I have an abstract class A:

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

class B : public A
{
public:
void f() {...}
};

B b;

However, the compiler does not like me calling f in the constructor of A.
But this seems like it should be okay since A is pure virtual, f will be
given in derived classes and exist.
During A's constructor, there is no B, thus no f() to call.

You can't call a virtual method form a base class constructor.

Ian
 
P

Peter_Julian

| I have an abstract class A:
|
| class A
| {
| public:
| A(){ f(); }
| virtual void f() = 0;
| };
|
| class B : public A
| {
| public:
| void f() {...}
| };
|
| B b;
|
| However, the compiler does not like me calling f in the constructor of
A.
| But this seems like it should be okay since A is pure virtual, f will
be
| given in derived classes and exist.
|

Consider that A's ctor is invoked and completed before B's ctor is
finally processed to completion. The vtable is available but unpopulated
during A's construction.

Recall the sequence of construction / destruction for an instance of B:

<- B's ctor is actually invoked here, vtable created but unpopulated
A()
<- populated vtable (at last)
B() // B's ctor is processed to completion

.... <- valid instance of B

~B()
~A()

If you call f() in B's ctor, the issue disappears since a populated
vtable is available for this instance of B.

#include <iostream>

class A
{
public:
A(){ std::cout << "A()\n"; }
virtual ~A(){ std::cout << "~A()\n"; }
virtual void f() = 0;
};

class B : public A
{
public:
B()
{
std::cout << "B()\n";
f();
}
~B(){ std::cout << "~B()\n"; }
void f() { std::cout << "B::f()\n"; }
};

int main()
{
B b;

return 0;
}

/*
A()
B()
B::f()
~B()
~A()
*/

Additionally, in C++ you could even have implemented the pure virtual
A::f() and called it from B::f().
 
P

puzzlecracker

Ian said:
During A's constructor, there is no B, thus no f() to call.

You can't call a virtual method form a base class constructor.

Ian

Mayer's descusses it at length - READ IT
 
R

Ron Natalie

However, the compiler does not like me calling f in the constructor of A.
But this seems like it should be okay since A is pure virtual, f will be
given in derived classes and exist.

The standard specifically says this is undefined behavior (virtual call
to pure virtual constructor during contruction or destruction).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top