Реализация внутреннего прокси в классе C ++

Я исследую кросс-платформенную библиотеку, опубликованную 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 вне класса.

1

Решение

Итак, вы пытаетесь перевести 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()
{

}
};
}
1

Другие решения

Вы не можете получить из неполного класса, и 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,

1

По вопросам рекламы [email protected]