2011-09-15 162 views
1

我想用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); 
    } 
} 

和內部MANB做:

inline manA^manB::GetA() 
{ 
    A *value = m_B->getA(); 
    manA^final; 
    final->UnmanagedObject = value; 
    return final; 
} 
+0

您需要在Derived類中實現Abstract類的所有純虛函數,否則您的派生類也將變爲Abstract類。 –

+2

我在代碼中看不到任何繼承。 –

+0

B不是來自A – Saurabh

回答

0

inline manB::manB() { m_B = new B; }

我認爲在這一行發生了錯誤,因爲B是從抽象類A派生的,並沒有實現在A類中定義的純函數。所以B也是一個抽象類。你永遠不能建立抽象類B的一個實例

+0

B不是來自A – Saurabh

0

我認爲這個問題是這樣的

return gcnew manA(value) 

你實例化的manA你聲明爲一個抽象類...

+0

我知道,但如果我不這樣做,那麼如何包裝_getA()_函數? – Saurabh

1

編寫封裝器不意味着寫同一個本地課程。不要讓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; 
}; 
+0

對不起。只是把它作爲我實際上在做什麼的一個例子 – Saurabh

+0

@Saurabh:給你一個問題。在真正的代碼中,你有從'manA'繼承的類嗎,必須'manA'實際上是抽象的嗎? –

+0

我有......所以它一定是抽象的。我想我已經得到了解決方案。我編輯了我的問題,回答 – Saurabh

0

利用仿製藥。

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