错过了一个虚拟函数调用



我在一个基类中有一个虚拟函数,以及从该基类派生的几个类。当其他函数被调用时,我没有得到对虚拟函数的调用。

我的基类:

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;
    }
};

我的派生类

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;
    }
};

我正在创建一个std::map列表来存储基于所用数据类型的派生类指针的列表。因为所有派生类都来自基类CCD_ 1,所以我返回类型为CCD_。

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)));
    }
}

检查数据类型值,如下所示:

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());
}

我得到的输出如下。我不明白真正的问题是什么,为什么它为类型eANYeWSTRING打印正确的值,为什么不为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

由于C_BOOL:virtual EDataTypeID getDataTypeId() const而不是virtual EDataTypeID getDataTypeID()const中的方法名错误,您得到了错误的结果。在C++11中,重写说明符将有助于避免此类错误。

您建议将ANY类中的getDataTypeID设置为纯虚拟函数。这将有两个目的:

  1. 它将突出显示代码中的问题(C_BOOL类中重写函数的名称不正确)-当您尝试使用C_BOOL对象时,您会发现存在编译错误
  2. 它还将阻止创建C_ANY类型的对象——这是一件好事,因为这样的对象不能赋予任何意义

旁注(除了评论中已经提到的以外):

  • 您不需要提供琐碎的构造函数和析构函数。也就是说

C_ANY_ELEMENTARY() :
    C_ANY() {
}
virtual ~C_ANY_ELEMENTARY() {
}

只是打字噪音(差不多。有一些黑暗的角落,但你不需要担心)。在你的所有层次结构中,你唯一需要的析构函数是

virtual ~C_ANY() {}
  • 您的switch语句中没有多个break,您无论如何都会返回

相关内容

最新更新