简体   繁体   中英

Polymorphism/inheritance issue with virtual class member function

I might have the wrong idea on exactly what polymorphism versus inheritance is, but basically what I'm trying to do is have classB derive from classA , and create a classB which overrides a pure virtual member function of classA , like so:


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


main:

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


As you can see, GetType() always returns CCBT_UNDEFINED . Keep in mind that CCodeBlock is meant to be a 'generic' version of CFunctionBlock (as well as a few other like-minded classes, some of which contain a CCodeBlock 'm_parent' member variable), and is supposed to inherit any CCodeBlock member variables & member functions, as well as override a specific list of functions contained in CCodeBlock.

How can this be achieved? Would I need to resort to using templates (if that's even possible)?

Bring comment as answer:

you don't need CCodeBlock:: when you declare member functions inside class CCodeBlock

There are several things wrong with your code. Member declarations should not have the class name as qualification (ie CCodeBlock:: should be removed from the declarations). Leaving it there makes the code ill formed.

Besides that, the destructor of a derived type will implicitly call the base class' destructor, and you should not do it. If you call it manually, the base subobject will be destroyed twice, probably causing undefined behavior (if the base destructor is not trivial).

Now the particular issue with your code in main was probably more like this:

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

In C++, qualifying a function call disables dynamic dispatch. The expression block->GetType() will be dispatched to the final overrider of the dynamic type of the object that the block pointer points to. But if you add the qualification: block->CCodeBlock::GetType() you are asking the compiler to call the overrider at the CCodeBlock level.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM