1

我正在调查 Dropbox 发布的跨平台库。以下java代码来自它。我想在我的 Visual c++ 中实现同样的东西;先看java代码

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++ 没有静态类定义。以下代码显示错误

class AsyncTask 
{
    public:
    virtual void execute();

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

        CppProxy(long tmpNativeRef)
        {

        }

        void execute()
        {

        }
    };
};

那么我如何实现内部静态类,它是外部类的子类。

4

2 回答 2

1

好的,所以您正在尝试将 Java 转换为 C++。

在java中,内部类默认有一个指向封闭类对象的隐藏指针。将其设为静态会删除该隐藏指针 - 换句话说,它不再绑定到包含对象,因此静态 => 在 C++ 中没有直接等价物,并且 C++ 内部类在这个意义上是静态的

在 C++ 中,您不能从不完整的类派生:内部类不能从其封闭类派生 => 您必须将CppProxy类声明放在AsyncTask. 如果你不想把它放在全局命名空间中,你可以把它放在另一个命名空间中说AsyncTaskInner

除了在 C++ 中非常特殊的情况外,要派生的类应该有一个虚拟析构函数,以便在删除指向基类的指针时允许适当的析构函数调用 => 您必须向 class 添加一个虚拟析构函数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()
        {

        }
    };
}
于 2016-03-04T12:40:38.087 回答
1

您不能从不完整的类派生,并且AsyncTask在其定义完成之前是不完整的。这就是class CppProxy : public AsyncTask失败的原因。

不过,解决方案很简单。只需让CppProxy类成为一个完全独立的类,并去掉多余的public。如果您需要访问CppProxyfrom的私有成员AsyncTask(否则,我首先不确定静态 Java 类的目的是什么),然后使用friend声明。

这是一个例子:

class AsyncTask 
{
    public:
    virtual void execute();

    friend class CppProxy;
};

class CppProxy : public AsyncTask 
{
    private:
    long LocalNativeRef;

    CppProxy(long tmpNativeRef)
    {

    }

    void execute()
    {

    }
};

请注意,override如果您使用支持 C++11 的编译器,则可以并且应该像在 Java 中一样使用。而且你显然需要一个虚拟析构函数AsyncTask

于 2016-03-04T12:26:27.543 回答