milesma
milesma

Reputation: 1591

compiler error if MFC RUNTIME_CLASS argument has namespace

I've got the answer, see bottom.

NOTE: "_AFXDLL" is not predefined for my case, linking statically to MFC.

I have code like this:

MyClass.h

namespace MyNameSpace
{
    class CMyClass : public CMyBase
    {
        DECLARE_DYNAMIC( CMyClass )
        ...
    }
}

MyClass.cpp

using namespace MyNameSpace;
IMPLEMENT_DYNAMIC( CMyClass , CMyBase)

caller

CMyBase* pObject = new MyNameSpace::CMyClass();
....
pObject->IsKindOf(RUNTIME_CLASS(MyNameSpace::CMyClass))

When compile, I've got error:

error C3083: 'classMyNameSpace': the symbol to the left of a '::' must be a type
error C2277: 'MyNameSpace::CMyClass::{ctor}' : cannot take address of this member function

I investigated the macro RUNTIME_CLASS and found that it eventually expanded to:

#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))

(CRuntimeClass*)(&MyNameSpace::CMyClass::classMyNameSpace::CMyClass)

Ideally, if it can expand to following code, then all good.

(CRuntimeClass*)(&MyNameSpace::CMyClass::classCMyClass)

Now my question:

  1. Is this a known issue from microsoft that "we can not use namespace in RUNTIME_CLASS"?

  2. A more practical question: For some reason(e.g. Classes from different namespace conflict), we can not "using namespace" in cpp file, how can we use Runtime Type Identification in MFC?

Answer from Hans Passant:

Microsoft has confirmed this bug here.

The workaround is quite smart, I copied it here:

Posted by BongoVR on 8/15/2006 at 2:39 AM
define YET ANOTHER MACRO and use it instead of RUNTIME_CLASS when namespace-qualified class names are to be used in the code:
#ifdef _AFXDLL
#define RUNTIME_CLASS_N(n, class_name) (n::class_name::GetThisClass())
#else
#define RUNTIME_CLASS_N(n, class_name) ((CRuntimeClass*)(&n::class_name::class##class_name))
#endif

This macro works in both builds (_AFXDLL defined and not defined).

Upvotes: 1

Views: 1475

Answers (2)

milesma
milesma

Reputation: 1591

Answer from Hans Passant:

Microsoft has confirmed this bug here.

The workaround is quite smart, I copied it here:

Posted by BongoVR on 8/15/2006 at 2:39 AM
define YET ANOTHER MACRO and use it instead of RUNTIME_CLASS when namespace-qualified class names are to be used in the code:
#ifdef _AFXDLL
#define RUNTIME_CLASS_N(n, class_name) (n::class_name::GetThisClass())
#else
#define RUNTIME_CLASS_N(n, class_name) ((CRuntimeClass*)(&n::class_name::class##class_name))
#endif

This macro works in both builds (_AFXDLL defined and not defined).

Upvotes: 1

ROBIN SCOTT
ROBIN SCOTT

Reputation: 33

The MFC macros can be limited, how about using dynamic_cast instead of IsKindOf(RUNTIME_CLASS(class_name))?

CMyBase* pObject =dynamic_cast<MyNameSpace::CMyClass>(new MyNameSpace::CMyClass);

Upvotes: 0

Related Questions