polymorphic call in abstract class's constructor

S

S. Levent Yilmaz

Is it possible to have the constructor in an interface call member functions
polymorphically? For instance:
==============================
// INTERFACE CLASS
class SomeInterface {
public:
virtual void foo()=0;
SomeInterface() { foo();}
};

// DERIVED CLASS
class Widget: public SomeInterface {
public:
void foo() { std::cout << "I am the widget" ;}
Widget(): SomeInterface() {};
};

//
int main() {
Widget w;
return 0;
}
================================
well, the compiler complains that there is no implementation for
"bla bla SomeInterface::foo()" (of course there isn't!)...

greetings,
levant.
 
V

Victor Bazarov

S. Levent Yilmaz said:
Is it possible to have the constructor in an interface call member functions
polymorphically?

No. Any call to a virtual function in a constructor (or destructor)
body is resolved statically, not polymorphically.

Victor
 
R

Ron Natalie

S. Levent Yilmaz said:
Is it possible to have the constructor in an interface call member functions
polymorphically? For instance:

No. You have two issues.

First, it's undefined behavior to make a virtual call to a pure virtual function in the
constructor or destructor.

Second, even if the function wasn't pure (just virtual), the overrider is selected
on the basis of the class for the constructor being run, not the most derived being
constructed. If Someinterface::foo() was just (non-pure) virtual, it's constructor
would call Somerinterface::foo() not WIdget::foo();
 
S

S. Levent Yilmaz

Indeed, I needed to implement such a behaviour:
- All derived classes carry out certain common operations during
construction
- These common operations are "similar" but not identical, and must be
defined in the particular derived class.

For example (a working version):

class Interface {
virtual void foo1() = 0;
virtual void foo2() = 0;
void foo3() = 0;
};

class Derived1: public Interface {
/* implement all pure virtuals */
Derived1 {
foo1(); foo2() ; foo3();
// do other stuff
}
};

class Derived2: public Interface {
/* implement all pure virtuals */
Derived2 {
foo1(); foo2() ; foo3();
// do other stuff
}
};
/* etc.... */


Well, instead of doing as above, I thought it would be neater to call all
these routine tasks (the foo's) automatically from a single place (Base
class's constructor would be a nice candidate but apparently it is not
working) and thereby guarantee that these routines are carried out for every
derived class.

So is there a neater way?

levent.
 
R

Ron Natalie

S. Levent Yilmaz said:
Indeed, I needed to implement such a behaviour:
- All derived classes carry out certain common operations during
construction
- These common operations are "similar" but not identical, and must be
defined in the particular derived class.

If I understand you correctly, you can do the following:

class Interface {
virtual void foo1() = 0;
...
void DoFoos() {
foo1(); foo2(); foo3();
}
};

class Derived1 : public Interface {
Derived1() {
DoFoos();
};
void foo1() { ... }
};

Here you are OK, DoFoos() is called in the context of Derived1's constructor
so the Derived1::foo1() is called. It's defined behavior as long as Derived1
is no longer abstract.
 
P

Peter Koch Larsen

Ron Natalie said:
If I understand you correctly, you can do the following:

class Interface {
virtual void foo1() = 0;
...
void DoFoos() {
foo1(); foo2(); foo3();
}
};

class Derived1 : public Interface {
Derived1() {
DoFoos();
};
void foo1() { ... }
};

Here you are OK, DoFoos() is called in the context of Derived1's constructor
so the Derived1::foo1() is called. It's defined behavior as long as Derived1
is no longer abstract.
You can, but the problem here is if you introduce a class that is derived
once again:

class Derived2: public Derived1 { ...}

Here the OP wants foo1, foo2 and foo3 of Derived1 called and this is not
going to happen.
A solution just popping up in my head is to use a template class like this:

template< class doubleconstruct >
class IMPL: public doubleconstruct
{
IMPL(): doubleconstruct() { foo1(); foo2(); foo3();}
};

(With some extra sugar if anything more than the empty constructor is
needed)

Kind regards
Peter Koch Larsen
 

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,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top