Я исследую кросс-платформенную библиотеку, опубликованную 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).
Таким образом, он реализует прокси c ++ внутри класса java для поддержки jni-компонента c ++ Object.
Но я хочу сделать это на языке MFC c ++, а не на языке Java (обычно для целей тестирования)
Так что я реализовал класс C ++ из верхнего Java-кода.
Но я обнаружил, что C ++ не имеет статического определения класса.
Фоллинг код показывает ошибку
class AsyncTask
{
public:
virtual void execute();
public static class CppProxy : public AsyncTask
{
private:
long LocalNativeRef;
CppProxy(long tmpNativeRef)
{
}
void execute()
{
}
};
};
Так как я могу реализовать внутренний статический класс, который subclsssing вне класса.
Итак, вы пытаетесь перевести Java на C ++.
В Java внутренний класс по умолчанию имеет скрытый указатель на объект включающего класса. При статическом удалении этот скрытый указатель — иными словами, он больше не привязан к содержащему объекту, поэтому static => не имеет прямого эквивалента во внутренних классах C ++ и C ++ в этом смысле статический
В C ++ вы не можете наследовать от неполного класса: внутренний класс не может быть производным от включающего его класса => вы должны поставить CppProxy
объявление класса за пределами AsyncTask
, Если вы не хотите помещать его в глобальное пространство имен, вы можете поместить его в другое пространство имен, скажем, AsyncTaskInner
За исключением особых случаев в C ++, класс, предназначенный для создания, должен иметь виртуальный деструктор, позволяющий правильно вызывать деструктор при удалении указателя на базовый класс => вы должны добавить виртуальный деструктор в класс AsyncTask
,
В C ++ вы не объявляете класс абстрактным, но вы можете сделать его абстрактным, если он содержит чисто виртуальный метод => Declare 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()
{
}
};
}
Вы не можете получить из неполного класса, и AsyncTask
является неполным, пока его определение не завершено. Вот почему class CppProxy : public AsyncTask
выходит из строя.
Решение простое, хотя. Просто сделай CppProxy
класс совершенно отдельный, и избавиться от лишнего public
, тоже. Если вам нужно получить доступ к частным членам CppProxy
от 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
как в Java, если вы используете компилятор с поддержкой C ++ 11. И вам, видимо, нужен виртуальный деструктор в AsyncTask
,