views:

73

answers:

2

Hi.

I have two classes, one of which is a subclass of another, and differs only by the fact that it contains an additional member variable to its parent. I am not using the default constructor, passing in a reference to a single object as the constructors parameter. What I would like is for the constructor of the parent to examine this object, and then determine whether to construct an instance of the parent class (in most cases) or the subclass (in a few specialised cases).

class Superclass 
{ 
    public: 
        Foo foo;

        Superclass(MyObject* object) 
        { 
            foo = object->GetFoo();

            if(object->CreateSubclass())
            {
                //Create Subclass
            }
            else
            {
                //Create Superclass
            }
        } 
}; 

class Subclass : public Superclass 
{ 
    public: 
        Barr barr;

        Subclass(MyObject* object)
        { 
            barr = object->GetBarr();
        } 
};

I'm aware of the factory design pattern, but don't want to have to have a factory object just for this. I'd rather duplicate the Superclass initialisation stuff into the Subclass (which seems bad) and then examine the object at each of the points where a Superclass is created and then call the appropriate constructor:

Superclass* class;
if(object->CreateSubclass())
{
    class = new Subclass(obj);
}
else
{
    class = new Superclass(obj);
}

Is this sort of thing possible, and if so how would I go about calling the subclasses constructor from Superclass constructor? I've tried making a call to Subclass(object), but I run into issues with both Superclass and Subclass needing to be defined before the other.

Thanks for any advice you can provide.

+3  A: 

I think this is impossible. The object is allocated before the constructor is called. Otherwise there would be no 'this' pointer and you couldn't initialize your variables. Think about it. Also notice that constructors don't return anything, yet the output of new YourClass() is a pointer to your new object.

Gary
to be more specific: the space that the object will occupy, will be reserved prior to the constructor call.
frunsi
yes, field references are just offsets into this space, correct?
Gary
That makes sense. I wasn't necessarily claiming it should work, just sort of stating what I wanted to do so either a solution or alternatives could be suggested.
Edd
+5  A: 

If you're set against a factory class, why not just a static function?

class Subclass
{
public:
    static Superclass* create(const MyObject* const object)
    {
        if (object->createSubclass())
        {
            return new Subclass(object);
        }
        else
        {
            return new Baseclass(object);
        }
    }

    // ...
}

// ...

Superclass* const myInstance = Subclass::create(myObject);

(I've put the static class in Subclass because it needs both the super and subclass implementations, but you could easily put it in a shared namespace or something, or even put the declaration in the base class but put the implementation in a cpp)

You've now got most of the benefits of a factory class, with no more code than you had before. You're just missing the ability to pass it around or easily refactor it into multiple implementations.

tenpn
This looks good. I'll have a bit of a play later when I get back onto that project.
Edd
It's the standard solution for this sort of thing.
Gary
If you like it you can accept it as the answer ;)
tenpn
I have done - I just needed to wait until I was back at work and checked through some things first. You have to wait 2 days before you can accept an answer anyway.
Edd