2016-03-04 40 views
1

我在調查由dropbox發佈的跨平臺庫。下面的java代碼是來自它的。 而我想在我的Visual C++中實現相同的東西; 在Java代碼C++類中的內部代理實現

public abstract class AsyncTask 
{ 
    public abstract void execute(); 

    public static final class CppProxy extends AsyncTask 
    { 
     private final long nativeRef; 
     private final AtomicBoolean destroyed = new AtomicBoolean(false); 

     private CppProxy(long nativeRef) 
     { 
      if (nativeRef == 0) throw new RuntimeException("nativeRef is zero"); 
      this.nativeRef = nativeRef; 
     } 

     private native void nativeDestroy(long nativeRef); 
     public void destroy() 
     { 
      boolean destroyed = this.destroyed.getAndSet(true); 
      if (!destroyed) nativeDestroy(this.nativeRef); 
     } 
     protected void finalize() throws java.lang.Throwable 
     { 
      destroy(); 
      super.finalize(); 
     } 

     @Override 
     public void execute() 
     { 
      assert !this.destroyed.get() : "trying to use a destroyed object"; 
      native_execute(this.nativeRef); 
     } 
     private native void native_execute(long _nativeRef); 
    } 
} 

先來看看這個Java代碼調用一些JNI C++類(它的AsyncTask的名稱相同)。 因此,它正在java類中實現C++代理來維護jni方面的C++對象。

但我想在MFC的c + +語言,而不是Java語言(通常用於測試目的)做它 所以我實現了從上層java代碼的C++類。 但我發現C++沒有靜態類定義。 Folloing代碼顯示錯誤

class AsyncTask 
{ 
    public: 
    virtual void execute(); 

    public static class CppProxy : public AsyncTask 
    { 
     private: 
     long LocalNativeRef; 

     CppProxy(long tmpNativeRef) 
     { 

     } 

     void execute() 
     { 

     } 
    }; 
}; 

所以,我怎麼能實現它subclsssing課外內部靜態類。

回答

1

好,所以你正試圖將Java翻譯成C++。

在java中,內部類默認有一個隱藏指針,指向封閉類的對象。靜態刪除隱藏的指針 - 不同地說,它不再與一個包含的對象綁定,所以static => C++和C++內部類沒有直接的等價關係在這個意義上是靜態的

在C++中,你不能從不完整的類:內部類不能從它的封閉類派生=>您必須將CppProxy類聲明放在AsyncTask之外。如果你不想把它放在全局命名空間,你可以把它放在另一個命名空間中說AsyncTaskInner

除了在用C非常特殊的情況++,旨在派生的類應該有一個虛析構函數,以允許適當的析構函數調用時你刪除一個指向基類的指針=>你必須在類AsyncTask上添加一個虛擬析構函數。

在C++中不聲明一個類是抽象的,但你可以把它抽象的,如果它包含一個純虛方法=>聲明execute爲純虛

你喜歡的東西結束:

class AsyncTask 
{ 
public: 
    virtual void execute() = 0; 
    virtual ~AsyncTask() {} 
}; 


namespace _AsyncTaskInner { 
    class CppProxy : public AsyncTask 
    { 
    private: 
     long LocalNativeRef; 
    public: 

     CppProxy(long tmpNativeRef) 
     { 

     } 

     void execute() 
     { 

     } 
    }; 
} 
+0

感謝您的親切和詳細的答案。 – MomAndDad

+0

@MomAndDad:不要忘記接受其中一個答案(勾選商標),以通知未來的讀者您不再需要幫助。沒有被接受的答案的問題在堆棧溢出中被視爲未關閉。 –

1

您不能從不完整的類中派生,並且AsyncTask在定義完成之前是不完整的。這就是爲什麼class CppProxy : public AsyncTask失敗。

雖然這個解決方案很簡單。只需使CppProxy類成爲一個完全獨立的類,並擺脫冗餘public。如果您需要從AsyncTask訪問CppProxy的私有成員(否則,我不確定靜態Java類的用途是什麼),然後使用friend聲明。

下面是一個例子:

class AsyncTask 
{ 
    public: 
    virtual void execute(); 

    friend class CppProxy; 
}; 

class CppProxy : public AsyncTask 
{ 
    private: 
    long LocalNativeRef; 

    CppProxy(long tmpNativeRef) 
    { 

    } 

    void execute() 
    { 

    } 
}; 

需要注意的是,你可以,而且應該在Java中,如果您使用的是啓用了11-C++編譯器使用override等。你顯然需要在AsyncTask中使用虛擬析構函數。

+0

謝謝... 因此,C++沒有內部類的子類外部類。 – MomAndDad