I have some class structure for the project I build for my company. At some point, I've seen a "usually unwanted" slicing of derived object could actually make my code efficient. Please observe:
class Base {
private:
int myType; //some constant here
public:
Base(): myType(1)
{
if(someTest())
{
myTest = 0; // signifies that this object is not working well for me
} // if the test succeeds, now I know this is a TYPE1 object
}
virtual bool someTest() { /* does make some validation tests */ }
int GetMyType() { return myType; }
// some more virtual functions follow
}
class Derived: public Base {
public:
Derived() : Base()
{
if( someTest() /*calls the derived*/ )
{
myType =2; // signifies that this is a TYPE2 object
/* Do something more*/
}
}
virtual bool someTest() { /* does make OTHER validation tests */ }
}
Now, if someTest() at Derived fails, this shows that my object is actually of Base type (myType = 1) or an faulty object (myType =0). Since these stuff are at constructors, and since I cannot use exception handling (embedded system); I thought of this:
{
// this is the object holder test block
// there is some latch - Base* - above = let's call it "ObjectHolder"
extern Base* ObjectHolder;
Derived * deriv = new Derived();
int dType = deriv->GetMyType() ;
if( dType == 1) // if test at base succeded but the one in derived failed
Base = & static_cast<Base> (*deriv); // specifically slice the object
else if(dType =2)
Base = deriv;
else
delete deriv; // this is a TYPE0 - nonworking- object so don't latch it
// use other implemented methods to do work ...
}
Now, why have I got such a design? Well, while I was designing the classes, since the methods of inner workings of "Base" (type 1) and "Derived" (type 2) classes differ (and there is a possibilty of type 3,4,5.... objects that are also different in inside) and since I didn't want to make and "if-then-else" check in every single method; I thought I'd make such a design and make the differing methods virtual so they could be called correctly (with thanks to polymorphism) whilst the common methods can be at some Base class.
But now, firstly, I'm not sure if that weird syntax ( & static_cast < Base > *deriv ) is correct (tested and seemed like working but I just want to make sure this is not because of luck); and secondly, I'm not sure if this is the "suggested method" to achive this - I kinda suspect that this syntax can cause memory leaks or something...
Changed code a little bit (also corrected syntax) to make the problem clearer.
Now, since the &(static_cast(*deriv)) is a faulty approach, I was thinking if I can make a "copy constructor" which bypasses the check at the Base class (which is actually the reason I try these stuff - I don't want that test to be run in some cases). Like below:
class Base {
// other stuff is like above
// cc:
Base(const Base &other) : myType(other.myType)
{
// no test is performed here!
}
// like other one above
}
With this written, I think I can do that now at the test block:
{
// the code above
if( dType == 1) // if test at base succeded but the one in derived failed
Base = new Base(*deriv); // specifically slice the object with cc
// code goes on ...
}
What about this?