Knowledge Drilling
Knowledge Drilling

Reputation: 1036

Inner Proxy implementation in C++ class

I'm investigating cross platform library published by dropbox. following java code is from it. And i want to implement same thing in my Visual c++; First Look at java code

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

This java code calls some jni c++ class (it is same name of AsyncTask). So it is implementing c++ proxy inside java class to maintain jni side c++ Object.

But i want to do it in MFC c++ language, not java language (usually for testing purpose) So i implemented c++ class from upper java code. But i have found c++ doesn't have static class definition. Folloing code shows error

class AsyncTask 
{
    public:
    virtual void execute();

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

        CppProxy(long tmpNativeRef)
        {

        }

        void execute()
        {

        }
    };
};

So How can i implement inner static class which is subclsssing outside class.

Upvotes: 1

Views: 703

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 148880

Ok so you are trying to translate Java to C++.

In java an inner class has by default a hidden pointer to an object of enclosing class. Making it static removes that hidden pointer - said differently, it is no longer bound to a containing object so static => no direct equivalent in C++ and C++ inner classes are static in that sense

In C++, you cannot derive from an incomplete class: an inner class cannot derive from its enclosing class => you must put the CppProxy class declaration outside of AsyncTask. If you do not want to put it in global namespace, you could put it in another namespace say AsyncTaskInner

Except in very special cases in C++, a class intended to be derived should have a virtual destructor to allow proper destructor calling when you delete a pointer to a base class => you must add a virtual destructor to class AsyncTask.

In C++ you do not declare a class to be abstract, but you can make it abstract if it contains a pure virtual method => declare execute as pure virtual

You end with something like:

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


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

        CppProxy(long tmpNativeRef)
        {

        }

        void execute()
        {

        }
    };
}

Upvotes: 1

Christian Hackl
Christian Hackl

Reputation: 27528

You cannot derive from an incomplete class, and AsyncTask is incomplete until its definition is complete. That's why class CppProxy : public AsyncTask fails.

The solution is easy, though. Just make the CppProxy class a completely separate one, and get rid of the redundant public, too. If you need to access private members of CppProxy from AsyncTask (otherwise, I'm not sure what the purpose of the static Java class would be in the first place), then use a friend declaration.

Here is an example:

class AsyncTask 
{
    public:
    virtual void execute();

    friend class CppProxy;
};

class CppProxy : public AsyncTask 
{
    private:
    long LocalNativeRef;

    CppProxy(long tmpNativeRef)
    {

    }

    void execute()
    {

    }
};

Note that you can, and should use override like in Java if you are using a C++11-enabled compiler. And you apparently need a virtual destructor in AsyncTask.

Upvotes: 1

Related Questions