Reputation: 1036
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
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
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