Home > database >  Pass parent pointer in derived constructor
Pass parent pointer in derived constructor

Time:11-26

So I was doing something like this:

    Base * pParentPtr

    // ... pParentPtr is used

    // Cast result pointer
    Derived* castedResult = (Derived*)pParentPtr;

    // Copy the referenced object to stack object
    Derived resultExplicitCopy = Derived(*castedResult);

    // run Derived class functions
    resultExplicitCopy.DeviredSpecialFunction();

    // Free memory allocated by factory
    delete pParentPtr;

Which means that the code uses pParentPtr but at the end we need it to be converted to Derived, then call a function that belongs only to Derived and then delete the initial pointer.

Although this works, the idea is to simplify the code. I thought on creating a contructor for Derived that takes a Base* for input:

Derived::Derived(Base* basePtr)
{
    // Cast result pointer
    Derived* castedResult = (Derived*)basePtr;

    // Copy the referenced object to stack object
    Derived resultExplicitCopy = Derived(*castedResult); // This looks bad

    // run Derived class functions
    resultExplicitCopy.DeviredSpecialFunction();

    *this = resultExplicitCopy; // ??? this seems weird and dangerous
}

Creating a Derived instance inside the constructor seems like a bad idea, also reseting the whole object before it actually exists.

So, is there a way of pasing Base's pointer to Derived's constructor and properly building it?

I'd like it to look like this:

    Base * pParentPtr

    // ... pParentPtr is used

    // Init derived with base
    derivedInstance = Derived(pParentPtr);


    // Free memory allocated by factory
    delete pParentPtr;

CodePudding user response:

The best way to deal with this would be to take a Base* in the constructor function and then manually setting the data fields in the constructor so for example. This is because when you call a constructor it will 'return' an instantiated version of that object to your specifications:

field1=basePtr->field1

I would avoid using the cast because it is a dangerous C cast as what it is doing is saying instead of treating what this pointer points to as having a Base type treat the memory as if it had a Derived type and if the memory doesn't match up there could be problems

CodePudding user response:

This code is valid only if pParentPtr points to an object of class Derived. If it's true, then you can do one of these depending on the actual use case:

  1. Directly call castedResult->DeviredSpecialFunction().

  2. If you don't like the -> syntax for some reason (i'm assuming you're doing hobby project or it is not a peer-reviwed code, otherwise -> is perfectly fine), then you can "transform" pointer to a reference: Derived& resultExplicitCopy = (Derived&)(*castedResult) (note the two added ampersands).

Also I agree with comments noting that you should revise your design such that:

  1. you don't blindly assume that pParentPtr points to Derived. Maybe the code above does the check already, but then still the following point holds:

  2. you certainly shouldn't allow the construction of Derived form pointer Base if such construction blindly assumed that a pointer points to a Derived. Usually a class may be used in a different places in program, so a class's constructor should be clear in a way that you know what objects it may accept by looking at its signature. Having a proper parameter type makes it formally correct, and formal correctness actually makes things clearer. If constructor assumes its paremeter points to Derived, it should accept a Derived*, and accepting 'Base* would be incorrect as it allows a pointer to a non-Derived` object to be passed into it by mistake. In such a case the compiler can't help you by type checking.

  • Related