Pointer to an abstract class
I am trying to wrap unmanaged c++ code using c++/cli. In C++/cli a class has to be declared abstract if it has all pure virtual functions. Now suppose I have the following code in C++:
class A{
public:
virtual ~A();
virtual void foo() = 0;
virtual void boo() = 0;
virtual void go开发者_Go百科o() = 0;
};
inline
A::~A()
{
}
class B
{
public:
B();
A* getA() const;
};
inline A* B::getA() const
{
//do something
return (A *) //of something;
}
As per above I can return A* without any errors. Now suppose I wrap the above code as follows:
public ref class manA abstract
{
public:
manA(A*);
virtual ~manA();
virtual void Foo() = 0;
virtual void Boo() = 0;
virtual void Goo() = 0;
private:
A* m_A;
};
inline
manA::~manA()
{
}
inline
manA::manA(A*)
{
//data marshalling to convert A* to manA
}
public ref class manB
{
public:
manB();
manA ^ GetA();
private:
B * m_B;
};
inline manB::manB()
{
m_B = new B;
}
inline manA ^ manB::GetA()
{
A *value = m_B->getA();
return gcnew manA(value);
}
now if I do the above I get a a class declared as 'abstract' cannot be instantiated error.
Is there any solution for this?
Note: the class A defines the interface for all possible implementations of it. So maybe there is a way to define manA such that it is not abstract and hence can be instantiated?
I found a solution to the problem:
Remove the constructor from manA and use a property
public:
property A* UnmanagedObject
{
void set(A* unmanagedObjPtr)
{
//Or other data marshalling
m_A = (A *)(unmanagedObjPtr);
}
}
and inside manB do:
inline manA ^ manB::GetA()
{
A *value = m_B->getA();
manA ^ final;
final->UnmanagedObject = value;
return final;
}
Writing a wrapper does not mean writing the same native class. Do not make manA
an abstract class and your problem is gone.
public ref class manA abstract
{
public:
manA(A*);
virtual ~manA();
virtual Foo() { m_A->foo(); }
virtual Boo() { m_A->boo(); }
virtual Goo() { m_A->goo(); }
//Also there should be an error like "Hey, What is the return type of those functions?"
//"virtual void Foo()" or "virtual int Foo()" or something else
private:
A* m_A;
};
inline manB::manB()
{
m_B = new B;
}
I think error occurs in this line, because B is derived from abstract class A and doesn't implement the pure function defined in class A. So B is also an abstract class. You can never create an instance of abstract class B.
I think the issue is this
return gcnew manA(value)
you are instantiating manA which you declared as an abstract class ...
Make use of generics.
public ref class manB
{
public:
manB()
{
m_B = new B();
}
generic<T> where T : manA
manA ^ GetA()
{
A *value = m_B->getA();
T ^ final = Activator::CreateInstance<T>();
final->UnmanagedObject = value;
return final;
}
/* or
generic<T> where T : manA
T ^ GetA()
{
A *value = m_B->getA();
T ^ final = Activator::CreateInstance<T>(); //this requires T has a public default contructor.
final->UnmanagedObject = value;
return final;
}
*/
!manB()
{
delete m_B; //don't forget to release the native resource
}
private:
B * m_B;
};
精彩评论