wrapping an abstract base class

  • Thread starter Thread starter Lee Crabtree
  • Start date Start date
L

Lee Crabtree

More fun wrapping unmanaged code...

I have a class heirarchy that I need to expose to C#, so I need to wrap all
the classes. That's not a big deal, except for the base class, which is
abstract. Since you can't instantiate an abstract class, I can't use a
pointer to the unmanaged type to handle the function calls.

Is there a good way to do this?

Lee
 
Since you can't instantiate an abstract class, it makes no sense to wrap it
(expose it to C#) since you can't use it anyway. So why do you feel
compelled to wrap it?

Brian
 
That's an excellent point that hit me two minutes after I posted my message.
I guess I've just done so much wrapping in the last week or so that I've got
wrap-happy.

Lee
 
I have a class heirarchy that I need to expose to C#, so I need to wrap
all
the classes. That's not a big deal, except for the base class, which is
abstract. Since you can't instantiate an abstract class, I can't use a
pointer to the unmanaged type to handle the function calls.

Abstract classes are half-built classes.
You must inherit from it and define the missing functionality.
Your compiler will tell you what methods needs to be created that are
incomplete in the abstract class.
 
I've found at least one reason why wrapping an abstract base class makes
sense.

Say the base class for several different other classes contains a lot of
functions that are inherited without being reimplemented. Without wrapping
the base class, you would have to wrap those functions in every single
inherited class. That seems like a lot of unnecessary work.

In C++, an abstract class can still have function definitions that actually
perform operations. Redefining those functions in every single derived
class is definitely unneeded work.

Any ideas?

Lee
 
Say the base class for several different other classes contains a lot of
functions that are inherited without being reimplemented. Without wrapping
the base class, you would have to wrap those functions in every single
inherited class. That seems like a lot of unnecessary work.

In that case consider my example. I introduced a method called
GetUnmanaged(), which is supposed to return the underlying native
implementation. In the abstract base, you don't know that pointer yet,
but in the derived classes you can just implement GetUnmanaged, which is
a trivial implementation. Can you live with that? ExecuteTwice did not
have to be duplicated in the derived classes.

Note that I used the new C++/CLI syntax. If you're using VC++ 2003,
you'll have to edit my code, but the concept is the same. This should
get you started.

Tom

// Wrap1.cpp : main project file.
// Output of the application is:
// UnmanagedDerived::Execute
// UnmanagedDerived::Execute

#include "stdafx.h"
#include <iostream>

using namespace System;

// native:

class UnmanagedBase
{
public:
virtual ~UnmanagedBase() { }
virtual void Execute() = 0;
void ExecuteTwice() { Execute(); Execute(); }
};

class UnmanagedDerived : public UnmanagedBase
{
public:
virtual void Execute() { std::cout << "UnmanagedDerived::Execute\n";
}
};

// managed:

ref class ManagedBased abstract
{
public:
virtual void Execute() { GetUnmanaged()->Execute(); }
void ExecuteTwice() { GetUnmanaged()->ExecuteTwice(); }
protected:
virtual UnmanagedBase* GetUnmanaged() = 0;
};

ref class ManagedDerived : public ManagedBased
{
public:
ManagedDerived() : ptr(new UnmanagedDerived) { }
~ManagedDerived() { delete ptr; }
protected:
virtual UnmanagedBase* GetUnmanaged() override { return ptr; }
private:
UnmanagedDerived* ptr;
};

int main(array<System::String ^> ^args)
{
ManagedDerived md;
md.ExecuteTwice();
return 0;
}
 
Back
Top