Reputation: 1591
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:
Is this a known issue from microsoft that "we can not use namespace in RUNTIME_CLASS"?
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
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
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