【问题标题】:Polymorphism/inheritance issue with virtual class member function虚拟类成员函数的多态性/继承问题
【发布时间】:2013-02-11 09:54:33
【问题描述】:

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


A 类:

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


B 类:

  /////////////////////
 // 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 中包含的特定函数列表。

如何做到这一点?我是否需要求助于使用模板(如果可能的话)?

【问题讨论】:

  • 顺便说一句,当你在类CCodeBlock中声明成员函数时,你不需要CCodeBlock::
  • 另外,类型不匹配。 CCodeBlock CFunctionBlock::GetType()CODE_BLOCK_TYPE CCodeBlock::GetType()。这段代码还能编译吗?
  • @billz 这是一个复制/粘贴错字,CFunctionBlock::GetType() 除外——这似乎一直是问题所在。删除 'CFunctionBlock::' 后,block->GetType() 现在返回 CCBT_FUNCTION。所以谢谢你!如果您将此作为答案发布,我会为您服务。
  • @Matthew 再次复制/粘贴错字。最初的名称是 JJCodeBlock、JJFunction 和 _JJ_BLOCK_TYPE,但为了简单起见,我决定编辑它们。这样做时犯了一些错误。我将编辑我的帖子以更正此问题。
  • @RectangleEquals:代码仍然格式不正确,还有一些其他问题。下次请记住,只有当问题确实代表您的真实代码时,人们才能帮助解决您的问题。也就是说,在复制导致问题的确切代码时要格外小心。

标签: c++ class function inheritance polymorphism


【解决方案1】:

将评论作为答案:

当你在类CCodeBlock中声明成员函数时,你不需要CCodeBlock::

【讨论】:

  • 实际问题出在 CFunctionBlock,而不是 CCodeBlock。但这已经足够接近了。再次感谢!
【解决方案2】:

您的代码有几个问题。成员声明不应以类名作为限定符(即 CCodeBlock:: 应从声明中删除)。将其留在那里会使代码格式错误。

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

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

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

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

【讨论】:

  • 这是有道理的。我已经从我的源代码中删除了所有基本的析构函数调用,谢谢!就block-&gt;CCodeBlock::GetType() 而言,目标是让block-&gt;GetType() 调用block-&gt;CFunctionBlock::GetType(),一旦我从CODE_BLOCK_TYPE CFunctionBlock::GetType(); 中删除'CFunctionBlock::' i>FunctionBlock.h
  • @RectangleEquals:你明白我在回答block-&gt;CCodeBlock::GetType() 时所说的话,对吧?我不确定是否足够清楚:如果您使用类名限定函数调用,则禁用动态调度并强制调用在该级别执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多