C ++类中的内部代理实现

时间:2016-03-04 12:06:01

标签: java c++ proxy-pattern

我正在调查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 side c ++ Object。

但我想用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的内部静态类。

2 个答案:

答案 0 :(得分:1)

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

但解决方案很简单。只需将CppProxy类完全分开,并删除多余的public。如果您需要从CppProxy访问AsyncTask的私有成员(否则,我不确定静态Java类的目的是什么),然后使用{{1}宣言。

以下是一个例子:

friend

请注意,如果您使用的是支持C ++ 11的编译器,则可以并且应该像Java一样使用override。你显然需要class AsyncTask { public: virtual void execute(); friend class CppProxy; }; class CppProxy : public AsyncTask { private: long LocalNativeRef; CppProxy(long tmpNativeRef) { } void execute() { } }; 中的虚拟析构函数。

答案 1 :(得分: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()
        {

        }
    };
}