C++ 缺少虚拟函数调用

C++ 缺少虚拟函数调用,c++,C++,我在一个基类中有一个虚函数,还有几个派生自该基类的类。我没有得到一个对虚拟函数的调用,而其余的被调用 我的基类: 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

我在一个基类中有一个虚函数,还有几个派生自该基类的类。我没有得到一个对虚拟函数的调用,而其余的被调用

我的基类:

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列表来存储基于所用数据类型的派生类指针列表。由于所有派生类都来自基类
cuany
I返回
cuany
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)));
    }
}
我得到的输出如下。我不明白真正的问题是什么,为什么它为类型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

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

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

您建议在
任何
类中使用
getDataTypeID
。这将有两个目的:

  • 它将突出显示代码中的问题(C_BOOL类中重写函数的名称不正确)-在尝试使用C_BOOL对象时,您将发现存在编译错误
  • 它还将阻止创建任何类型的对象——这是一件好事,因为这些对象不能赋予任何意义
  • 旁注(除评论中已提及的内容外):

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

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

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

    您建议将
    getDataTypeID
    放在
    任何
    a类纯虚拟函数中。这将有两个目的:

  • 它将突出显示代码中的问题(C_BOOL类中重写函数的名称不正确)-在尝试使用C_BOOL对象时,您将发现存在编译错误
  • 它还将阻止创建任何类型的对象——这是一件好事,因为这些对象不能赋予任何意义
  • 旁注(除评论中已提及的内容外):

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

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

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

    旁注:请不要像MACRO_S那样命名类。在new之后不需要nullptr测试(它会引发异常,除非您使用new(std::nothrow)T)@DieterLücking,而且-即使没有使用
    new
    的抛出版本,
    返回((ptr!=NULL)?ptr:NULL)
    仍将与
    return ptr
    具有完全相同的效果。旁白:旁白:请不要像MACRO_S那样命名类。在new之后不需要null ptr测试(它会引发异常,除非您使用new(std::nothrow)T)@DieterLücking,而且-即使没有使用
    new
    的抛出版本,
    return((ptr!=NULL)?ptr:NULL);
    仍将具有与
    返回ptr
    完全相同的效果。旁白:答案正确,但零/NULL/缺失类型可能有用(但应该是显式的)@DieterLücking,100%同意-这就是为什么C_NULL应该是集合中的另一种类型,而不是C_ANY本身。回答正确,但是零/NULL/缺失类型可能有用(虽然应该是明确的)@DieterLücking,100%同意-这就是为什么C_NULL应该是集合中的另一种类型,而不是C_ANY本身。
    virtual ~C_ANY() {}