Function that changes behaviour for superclass

95 Views Asked by At

I have a tool that's been subclassed. A bug has been reported where the subclass has taken a value from the superclass it shouldn't have taken: mySuperclass.SetMyVar() is being called for a subclass object.

If I can't make SetMyVar private – because it is being called in initialisation that happens for both classes – can I make the behaviour dependent on whether this is a superclass item or subclassed item?

The fix suggested – to supply SetMyVar() for the subclass – presents maintenance issues should the superclass be derived from again.

[Still, if I used b.SetMyVar() and it didn't do it then I might have another bug to contend with... maybe the subclass implementation is right.]

Something like this:

class A
{
public:
    A() {myVar = 20; }

    void SetMyVar(int val)
    {
        //eg (typeid (this).name() == "class A*") // doesn't work
        //eg (dynamic_cast <A*>(this)) // doesn't work

[something here to make it happen for only objects of type superclass]
        {
            myVar = val;
        }
    }

    int myVar;
};


class B : public A
{
public:
    B() { myVar = 10; }
};

int main(...)
{
    A a;
    B b;

    a.SetMyVar(2);
    b.SetMyVar(3); < -- this should not set myVar 

    std::cout << a.myVar << " : " << b.myVar;

    return 0;
}
1

There are 1 best solutions below

2
Adrian Mole On

As mentioned in the comments, if you want to distinguish between a base class and a derived class dynamically (such as by using typeid), then your base class must have a virtual function.

The simplest one to add is a (default) virtual destructor; a typeid() comparison can then be used to spot a call to the base class function from a derived class object:

#include <iostream>
#include <typeinfo>

class A {
public:
    A() { myVar = 20; }
    virtual ~A() = default; // This makes the class polymorphic
    void SetMyVar(int val)
    {
    //  if (typeid(this) == typeid(A*)) {// Wrong: "this" is always of type A* here!
        if (typeid(*this) == typeid(A)) {
            myVar = val;
        }
    }
    int myVar;
};

// Remaining code as you have it ...

Note, also, that my code does the typeid check on the dereferenced this pointer (i.e. on the actual object from which the function is being called). A typeid check on the this pointer itself will always yield the type of a pointer to the class in which the code is defined.