开发者

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;
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜