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
> 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
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
> 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
Tamas Demjen - 11 Nov 2005 22:02 GMT
> 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;
}