指向抽象类的指针

Pointer to an abstract class

本文关键字:指针 抽象类      更新时间:2023-10-16

我正在尝试使用c++/cli包装非托管c++代码。在c++/cli中,如果一个类具有所有纯虚函数,则该类必须声明为抽象。现在假设我有下面的c++代码:

class A{
public:
  virtual ~A();
  virtual void foo() = 0;
  virtual void boo() = 0;
  virtual void goo() = 0;
};
inline
A::~A()
{
}
class B
{
public:
  B();
  A* getA() const;
};
inline A* B::getA() const
{
  //do something
  return (A *) //of something;
}

如上所述,我可以返回A*而不会出现任何错误。现在假设我将上述代码包装如下:

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

现在,如果我这样做,我得到一个一个类声明为'抽象'不能被实例化错误。

有什么解决办法吗?

注意:类A定义了它的所有可能实现的接口。所以也许有一种方法来定义manA,使它不是抽象的,因此可以实例化?

我找到了解决问题的方法:

manA移除构造函数,并使用属性

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

编写包装器并不意味着编写相同的本机类。不要让manA成为一个抽象类,你的问题就解决了。

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

我认为这一行出现了错误,因为B是从抽象类A派生出来的,没有实现类A中定义的纯函数,所以B也是一个抽象类。永远不能创建抽象类b的实例

我认为问题是这样的

return gcnew manA(value)

充分利用泛型。

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