Since we don't have a managed C++ forum I thought I would put this here:
Take the following code that is in one DLL:
Code:#pragma once using namespace System; #include "NativeClass.h" namespace Managed { public interface class ITest { public: virtual void Foo(); virtual void SetNativeClass(NativeClass *pClass); }; public ref class Test abstract : public ITest { public: Test() : m_pNativeClass(0) { } virtual void Foo() { } virtual void SetNativeClass(NativeClass *pClass) = 0; public: NativeClass *m_pNativeClass; }; }Code:#pragma once class NativeClass { public: NativeClass() { } };
And the following code in another DLL:
And the following errors from compiling the second DLL:Code:// ManagedObject.h #pragma once using namespace System; #include "NativeClass.h" namespace Managed { public ref class ManagedObject : public Test { public: ManagedObject() { } virtual void SetNativeClass(NativeClass *pClass) { m_pNativeClass = pClass; } }; }
Let's take the errors one by one here:1>ManagedObject.cpp
1>e:\dev\managedtest\managedobject\ManagedObject.h (11) : warning C4570: 'Managed::ManagedObject' : is not explicitly declared as abstract but has abstract functions
1> 'void Managed::Test::SetNativeClass(NativeClass *)' : is abstract
1> e:\dev\managedtest\managedtest\debug\managedtest.d ll : see declaration of 'Managed::Test::SetNativeClass'
1>e:\dev\managedtest\managedobject\ManagedObject.h (18) : error C2248: 'Managed::Test::m_pNativeClass' : cannot access private member declared in class 'Managed::Test'
1> e:\dev\managedtest\managedobject\ManagedObject.h(1 2) : see declaration of 'Managed::Test::m_pNativeClass'
1> e:\dev\managedtest\managedtest\debug\managedtest.d ll : see declaration of 'Managed::Test'
This makes no sense at all. Clearly I have implemented the abstract function in ManagedObject. This means that ManagedObject is NOT abstract. However the class it derives from...namely Test IS abstract b/c it has at least one pure virtual function. This error is bogus from what I can see.1>e:\dev\managedtest\managedobject\ManagedObject.h (11) : warning C4570: 'Managed::ManagedObject' : is not explicitly declared as abstract but has abstract functions
First of all SetNativeClass() is abstract in Test() but not abstract in ManagedObject. When you look at the declaration of SetNativeClass() in Test you will see this. Another bogus error.1> 'void Managed::Test::SetNativeClass(NativeClass *)' : is abstract
1> e:\dev\managedtest\managedtest\debug\managedtest.d ll : see declaration of 'Managed::Test::SetNativeClass'
I beg your pardon? Since when is m_pNativeClass inaccessible to a class that derives from a base that gives protected access to it? It's not the old problem of passing in an object of type Test * and then trying to set m_pNativeClass from that pointer. That is clearly wrong since protected applies to your own instance and not the instance of another class of the same type. But even if I set m_pNativeClass to public it will still say in the second DLL that it is private to Test even though I'm deriving from Test. Another bogus error.1>e:\dev\managedtest\managedobject\ManagedObject.h (18) : error C2248: 'Managed::Test::m_pNativeClass' : cannot access private member declared in class 'Managed::Test'
1> e:\dev\managedtest\managedobject\ManagedObject.h(1 2) : see declaration of 'Managed::Test::m_pNativeClass'
1> e:\dev\managedtest\managedtest\debug\managedtest.d ll : see declaration of 'Managed::Test'
This occurs in MSVC 2005 and MSVC 2008. What is going on here?
My .NET book specifically states that protected access means that members of the class can access the member or data and derived classes in other assemblies can also access the member or the data.
However this does not seem to be true according to this error. The really really bad part about this is if you change the data type of m_pNativeClass to a POD type it works like a gem.
Now if you don't implement SetNativeClass() in ManagedObject the compiler will say that you must implement the function Managed::ITest::SetNativeClass(NativeClass *). But when I have clearly implemented it, it acts as if I have not. In fact it can see Managed::Test b/c the inheritance works fine.
If you remove the offending pointer and get everything compiling and put some assignment code in Test::SetNativeClass() and ManagedObject::SetNativeClass() so you can set breakpoints more odd things happen. So let's say you put int x= 5; in Test::SetNativeClass() and int x = 5; int ManagedObject::SetNativeClass(). The following code will surprise you.
What is weird here is that the constructor for ManagedObject does get called but SetNativeClass() will call the BASE version instead of the derived version. How in the world can you construct a derived object, verify it constructed via breakpoints in the derived constructor, and yet when the call is made hit the breakpoint in the Base version of SetNativeClass()? Very odd. Whatever happened to polymorphism?Code:ManagedObject ^object = gcnew ManagedObject(); object.SetNativeClass(0);



LinkBack URL
About LinkBacks



