Are pure virtual constructors possible ?

Hi there,

I'm attempting to write a base class and some derived classes for Phidget modules and am currently wondering how I might include a virtual pure constructor in the base class so that it has to be implemented in each derived class.

I want to do this as I need to force each derived class to provide a constructor that will take a particular type of parameter, so I considered the following code (repeated for brevity) :

1
2
3
4
5
6
7
class Interface_PhidgetModule {
public:
    Interface_PhidgetModule();
    Interface_PhidgetModule(const Interface_PhidgetModule& orig);
    virtual Interface_PhidgetModule(CPhidgetHandle hnd)=0;
    virtual ~Interface_PhidgetModule();
}


However in the derived class I would have to implement the pure virtual constructor thus :
1
2
3
4
5
class PhidgetAccelerometer : public Interface_Phidgetmodule {
 virtual Interface_PhidgetModule(CPhidgetHandle hnd);

..
}


.. which obviously is invalid !

So how might I achieve ensuring a particular constructor is implemented in a derived class ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <cstdlib>
#include <iostream>

using namespace std;

class A
{
      public:
      A();
};

class B: public A
{
};

A::A()
{
      cout << "A constructed" << endl;
}

int main(int argc, char *argv[])
{
    A a;
    B b;
    cin.get();
    return EXIT_SUCCESS;
}


The output for this is:
A constructed
A constructed

so as far as I can tell, if there is no constructor in the child, the parent one is called


Threw in a constructor for B and both A and B were called for it.
Last edited on
Constructors cannot be virtual.

You could go for two stage construction and provide a pure virtual Initialise() method that is called after the constructor.
Last edited on
If you want a particular bass class constructor to be called in a particular derived class, make the derived class ctor call it
PhidgetAccelerometer(CPhidgetHandle hnd): Interface_PhidgetModule(hnd) { ... }

If this is not what you mean,
I don't get it...
I need to force each derived class to provide a constructor that will take a particular type of parameter

Can you explain a little bit?


You can't let the derived tell the base ctor what to do, because the derived object is a kind of the base, so the base ctor is automatically call whenever a derived is created. (except that you're using virtual inheritance, but that's another issue...)
Last edited on
wmheric,

If you want a particular bass class constructor to be called in a particular derived class, make the derived class ctor call it


No I need to have the derived class implement a virtual constructor. i.e. I want to force the derived class to have a constructor with a particular prototype. I cannot do this by placing it in the base clase as instantiating with this base constructor would create an instance of the base class and NOT the derived class.

Warnis,

I see how that works cheers. The only drawback is that it's not abstract in the base class, thus it's possible for the derived class to not (i.e. programmer forgets) to implement it.
In other words, you want the user to call your base class constructor that takes a handle because aside from copy construction, that is the only valid way to construct the base. If so, then eliminate the base class' default constructor or make it inaccessible (protected).
It sounds to me like this is a "smart loader" kind of deal. You want to create a different object depending on the argument passed to the virtual ctor, right? Or am I misunderstanding?

This cannot be done with a constructor. As jsmith said, constructors cannot be virtual. This is because you need to know what kind of object you have before the constructor is called.

If I'm understanding right... the end result is you want to do something like this:

 
Interface_PhidgetModule* obj = new <Dont know which class you want yet>( phidget_handle );


Where the exact type of class created depends upon the passed 'phidget_handle'. Is this correct?


I'm doing something like this in a program I'm working on -- so I have a solution for you. But it's awfully wordy so I don't want to post it if it's not what you're looking for.

Let me know if I'm on base or not.


EDIT: actually there's an easier solution than what I originally had in mind since you have a class here (CPhidgetHandle) that is the deciding factor. Just give CPhidgetHandle a virtual function which creates the necessary object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CPhidgetHandle
{
public:
  virtual Interface_PhidgetModule* CreateModule() = 0;  // makes the necessary module
};

class Handle_A : public CPhidgetHandle
{
public;
  virtual Interface_PhidgetModule* CreateModule() { return new Inteface_A(*this); }
};

//------------------

Interface_PhidgetModeule* md = hnd->CreateModule();
// ...
delete md;
Last edited on
Disch,

Thanks for your reply, but that's not quite what I wanted.

I wanted ANY derived class to have a constructor which will accept a CPhidgetHandle parameter as the ONLY argument. i.e. instantiation of the derived class can only take place with a CPhidgetHandle parameter passed to the constructor.

If I put this as a method in the BASE class, then I can only make an object of the base class (using this constructor prototype), I cannot create a DERIVED class with this constructor method.

I'm perhaps not describing it too well but it's not too significant a problem at the moment, I'm jsut trying to adopt some good programming skills.

Unfortunately I cannot (well i could with a lot of effort) alter the CPhidgetHandle as it's code not written by myself and so tinkering would probably upset other functions as well
Hrm. Well then I don't think there's any way to do what you want. There's no way to enforce that a child class has a specific ctor. Any class can have any ctors it wants. You just have to be sure you design your ctors the way you want.
No I need to have the derived class implement a virtual constructor. i.e. I want to force the derived class to have a constructor with a particular prototype.


First, as has already been said you cannot have virtual constructors. It isn't possible, so lets take that off the table immediately. The purpose of virtual functions is to allow a caller to invoke a function from a base class pointer. Constructors are very different from other member functions so the concept of a virtual constructor doesn't make any sense. Only non-static member functions (excluding all forms of constructors) can be virtual.

Therefore, if the base class only has the one constructor that takes a handle, you will be forced to implement a derived class constructor that invokes the base class constructor with the correct arguments (which you would be forced to code into your derived class constructor's initialization list). Whether the derived class handle has the same signature or not is irrelevant. It is up to you to decide how to code that derived class which can generate handles as part of its behavior or allow the caller of the constructor to pass in the handle. Either way, the derived class would construct the base class and could be forced to provide a handle, somehow simply be limiting the kinds of constructor(s) declared and defined within the base class.

Another option would be to use a factory. Construct the factory and then call some virutal function of the factory class which will construct the objects properly. If the factory::create method was a friend of the classes in question, the constructors could be protected forcing users to only construct objects via the virtual factory methods. In that case, the factory's create methods would be like an extension of the interface but since they are part of a separate, previously constructed object those functions can be virtual. Would that work for you? It'd be pretty simple to try I think.
kempofighter,

Thanks for your reply, I think you've answered what I wanted to know... cheers. I haven't implemented what you've said as I've 'got round' the problem for now and have moved on to other problems (see other posts on this forum by me !)

Oh well.. noone said C++ was going to be easy
Topic archived. No new replies allowed.