kar
kar

Reputation: 495

missing out a virtual function call

I have a virtual function inside a base class and several derived class from that base class. I am not getting a call to a virtual function while the rest gets called.

my Base class:

class C_ANY
{
public:
    enum EDataTypeID {
        eANY = 1, eBOOL, eSINT, eINT, eDINT, eLINT, eUSINT,
        eUINT, eUDINT, eULINT, eBYTE, eWORD, eDWORD, eLWORD,
        eDATE, eTIME_OF_DAY, eDATE_AND_TIME, eTIME, eREAL, eLREAL, eSTRING,
        eWSTRING
    };

    C_ANY(void);
    virtual ~C_ANY() {}

    virtual EDataTypeID getDataTypeID() const {
        return C_ANY::eANY;
    }
};

my derived classes

class C_ANY_ELEMENTARY : public C_ANY {

public:

    C_ANY_ELEMENTARY() :
        C_ANY() {
    }

    virtual ~C_ANY_ELEMENTARY() {
    }

    virtual EDataTypeID getDataTypeID() const {
        return C_ANY::eANY;
    }
};

class C_ANY_BIT : public C_ANY_ELEMENTARY {

public:
    virtual ~C_ANY_BIT() {
    }

protected:
    C_ANY_BIT() :
        C_ANY_ELEMENTARY() {
    }
};

class C_BOOL : public C_ANY_BIT {

public:
    typedef bool ValueType;

    C_BOOL(void);

    virtual ~C_BOOL() {
    }

    virtual EDataTypeID getDataTypeId() const {
        return C_ANY::eBOOL;
    }
};

class C_ANY_STRING : public C_ANY_ELEMENTARY {

public:
    virtual ~C_ANY_STRING() {}

    C_ANY_STRING() {
    }
};

class C_WSTRING : public C_ANY_STRING
{
public:
    C_WSTRING() {
    }

    virtual ~C_WSTRING() {
    }

    virtual EDataTypeID getDataTypeID() const {
        return C_ANY::eWSTRING;
    }
};

I am creating a std::map list to store the list of derived class pointer based on the datatype used. since all the derived classes are from base class C_ANY I return a pointer of type C_ANY class.

C_ANY * DatatypeHandler::CreateDataTypeInstance(C_ANY::EDataTypeID type)
{
    switch (type)
    {
      case C_ANY::eANY: {
        C_ANY *ptr = new C_ANY();
        return ((ptr != NULL) ? ptr : NULL);
      }
      break;

      case C_ANY::eBOOL: {
        C_BOOL *ptr = new C_BOOL();
        return ((ptr != NULL) ? ptr : NULL);
      }
      break;

      case C_ANY::eWSTRING: {
        C_WSTRING *ptr = new C_WSTRING();
        return ((ptr != NULL) ? ptr : NULL);
      }
      break;
    }

    return NULL;
}

typedef std::map<C_ANY::EDataTypeID, C_ANY*> DataTypeList;
DataTypeList     _dataTypeList;

void CreateDataTypeInstance(C_ANY::EDataTypeID type)
{
    DataTypeList::const_iterator iter = _dataTypeList.find(type);
    if (iter == _dataTypeList.end())
    {
        _dataTypeList.insert(make_pair(type, DatatypeHandler::getInstance().CreateDataTypeInstance(type)));
    }
}

Check for datatype value as below:

void checkDataType(C_ANY::EDataTypeID type) {

printf("\n UpdataDataVar : %d, %d", type,_dataTypeList[type]->getDataTypeID());
    DataTypeList::const_iterator iter = _dataTypeList.find(type);
    printf("\n iterator : %d, %d", iter->first, iter->second->getDataTypeID());
}

What I get as output is below. I don't understand what is the real issue and why it prints correct value for type eANY and eWSTRING and why not for eBOOL.

UpdataDataVar : 2, 1  <<<< Issue is This <<<<<<
iterator : 2, 1       <<<< Issue is This <<<<<<
UpdataDataVar : 22, 22
iterator : 22, 22
UpdataDataVar : 1, 1
iterator : 1, 1

Upvotes: 0

Views: 94

Answers (2)

SergeyA
SergeyA

Reputation: 62603

You suggest you make your getDataTypeID within ANY class a pure virtual function. This will serve two purposes:

  1. It will highlight the problem in your code (incorrect name for the overriding function in C_BOOL class) - you will find out there is a compilation error when you try to use C_BOOL object
  2. It will also prevent creation of objects of C_ANY type - which is a good thing, since such objects can not confer any meaning.

Side note (in addition to already mentioned in the comments):

  • You do not need to provide trivial constructors and destructors. That is,

:

C_ANY_ELEMENTARY() :
    C_ANY() {
}

virtual ~C_ANY_ELEMENTARY() {
}

is just typing noise (almost. There are some dark corners, but you do not need to worry about those). In all your hierarchy, the only destructor you need is

virtual ~C_ANY() {}
  • You do not multiple breaks in your switch statement - you are returning anyways.

Upvotes: 1

M. Bogdanov
M. Bogdanov

Reputation: 86

You get wrong result because of wrong method name in C_BOOL: virtual EDataTypeID getDataTypeId() const instead of virtual EDataTypeID getDataTypeID()const. In C++11 override specifier will help to avoid such errors.

Upvotes: 4

Related Questions