虚函数成员函数的多态/继承问题

时间:2013-02-26 03:21:39

标签: c++ class function inheritance polymorphism

我可能对多态与继承究竟是什么有错误的想法,但基本上我要做的是 classB 派生自 classA ,并创建一个 classB ,它会覆盖 classA 的纯虚拟成员函数,像这样:


CLASSA:

  /////////////////
 // CodeBlock.h //
/////////////////

typedef enum {
    CCBT_UNDEFINED,
    CCBT_FUNCTION,
    //...
} CODE_BLOCK_TYPE;

class CCodeBlock {
public:
    CCodeBlock::CCodeBlock();
    CCodeBlock::CCodeBlock(CString& source, DWORD startPos);
    CCodeBlock::~CCodeBlock();
    virtual CODE_BLOCK_TYPE CCodeBlock::GetType() = 0

    CString m_code;
    DWORD m_startPos;
    DWORD m_length;
    int m_numLines;
}

  ///////////////////
 // CodeBlock.cpp //
///////////////////

//...
CCodeBlock::CCodeBlock(CString& source, DWORD startPos) : m_code(source), m_startPos(startPos) {
    m_length = m_code.GetLength();
}

CODE_BLOCK_TYPE CCodeBlock::GetType() {
    return CCBT_UNDEFINED;
}


CLASSB:

  /////////////////////
 // FunctionBlock.h //
/////////////////////

#include "CodeBlock.h"

class CFunctionBlock : public CCodeBlock {
public:
    CFunctionBlock::CFunctionBlock();
    CFunctionBlock::CFunctionBlock(CString& source, DWORD startPos);
    CFunctionBlock::~CFunctionBlock();
    CODE_BLOCK_TYPE CFunctionBlock::GetType();
}

  ///////////////////////
 // FunctionBlock.cpp //
///////////////////////

//...
CFunctionBlock::CFunctionBlock(CString& source, DWORD startPos)
{
    m_code = source;
    m_startPos = startPos;
}

CFunctionBlock::~CFunctionBlock()
{
    CCodeBlock::~CCodeBlock();
}

CODE_BLOCK_TYPE CFunctionBlock::GetType()
{
    //////////////////////////////
    // >> NEVER GETS CALLED! << //
    //////////////////////////////
    return CCBT_FUNCTION;
}


主要

CCodeBlock *block = new CFunctionBlock(L"function hello(){ print('hello') }", iPos)
CODE_BLOCK_TYPE type = block->GetType(); // ALWAYS RETURNS CCBT_UNDEFINED!


如您所见, GetType() 始终返回 CCBT_UNDEFINED 。请记住,CCodeBlock应该是CFunctionBlock的“通用”版本(以及一些其他类似头脑的类,其中一些包含CCodeBlock'm_parent'成员变量),并且应该继承任何CCodeBlock成员变量&安培;成员函数,以及覆盖CCodeBlock中包含的特定函数列表。

如何实现这一目标?我是否需要使用模板(如果可能的话)?

2 个答案:

答案 0 :(得分:1)

回答评论:

在类CCodeBlock::

中声明成员函数时,您不需要CCodeBlock

答案 1 :(得分:1)

您的代码有几个问题。成员声明不应将类名作为限定条件(即CCodeBlock::应从声明中删除)。离开它会使代码生成错误。

除此之外,派生类型的析构函数将隐式调用基类的析构函数,您不应该这样做。如果手动调用它,基础子对象将被销毁两次,可能导致未定义的行为(如果基础析构函数不是很简单)。

现在main中代码的特殊问题可能更像是:

CCodeBlock *block 
     = new CFunctionBlock(L"function hello(){ print('hello') }", iPos)
CODE_BLOCK_TYPE type = block->CCodeBlock::GetType();
//                            ^^^^^^^^^^^^

在C ++中,限定函数调用会禁用动态调度。表达式block->GetType()将被分派到block指针指向的对象的动态类型的最终覆盖。但是如果添加限定条件:block->CCodeBlock::GetType(),则要求编译器在CCodeBlock级别调用覆盖。