2016-03-04 100 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