android — функция-член базового класса напрямую обращается к функции-члену дочернего класса?

Возможно ли, чтобы функция-член базового класса могла напрямую обращаться к функции-члену дочернего класса?

Я нашел код от Androind, BufferQueue наследуется BnSurfaceTexture, и имеет одну функцию-член «requestBuffer».

В базовом классе BnSurfaceTexture, Я нашел это просто вызвать requestBuffer напрямую.

Как работает базовый класс BnSurfaceTexture знаете функцию «requestBuffer»?

Спасибо

Функция-член базового класса:

status_t BnSurfaceTexture::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case REQUEST_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int bufferIdx   = data.readInt32();
sp<GraphicBuffer> buffer;
/* it call requestBuffer directly */ <--------
int result = requestBuffer(bufferIdx, &buffer);
reply->writeInt32(buffer != 0);

Объявление дочернего класса & реализация:

class BufferQueue : public BnSurfaceTexture {

private:
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
ATRACE_CALL();
ST_LOGV("requestBuffer: slot=%d", slot);
Mutex::Autolock lock(mMutex);
...
return NO_ERROR;
}

0

Решение

Как базовый класс BnSurfaceTexture узнает функцию requestBuffer?

Эта функция должна быть по крайней мере объявлен (он мог быть определен с помощью некоторой реализации по умолчанию) в базовом классе, и он должен быть virtual,

Итак, во время компиляции компилятор видит, что такая функция существует.
Вызов функции разрешается во время выполнения. Это полиморфизм.


Крошечный пример:

class Base
{
public:
virtual void f() { /* Base */ } // could be pure virtual
virtual void g() { f(); };
};

class Derived: public Base
{
public:
virtual void f() { /* derived */ }
};

Когда у тебя есть

Base* pB = new Derived;
pB->g();

g() позвоню Derived::f;

2

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

Просто убедитесь, что функция базового класса объявленный, и производный класс определить до определение функции базового класса определение. Вот пример

#include <iostream>

class Base
{
public :

void call_derived ();
};

class Derived : public Base
{
public :

void derived_fun ()
{
std::cout << "Derived class member function called!" << std::endl;
}
};

void Base::call_derived ()
{
static_cast<Derived *>(this)->derived_fun();
}

int main ()
{
Derived dobj;
dobj.call_derived();

return 0;
}

Тем не менее, это использование static_cast небезопасно, компилятор не будет жаловаться, если вы попытаетесь call_derived на незавершенном объекте. Тем не менее, вы можете добавить утверждение assert(dynamic_cast<Derived *>(this)по крайней мере в режиме отладки, для целей отладки. Кроме того, вы можете объявить конструктор базового класса, деструктор protected, чтобы предотвратить создание незавершенного объекта или попытки уничтожить производный объект, пока основание не является полиморфным

Тем не менее, приведенный выше код не очень распространен в реальном мире. Существуют и другие более продвинутые методы, такие как CRTP, которые также используют static_cast и обеспечить статический полиморфизм без virtual функции.

Этот ответ может быть не совсем то, что вы хотите. Это только показывает, что можно вызывать производные члены класса в базовом классе, даже если он не определен в базе вообще. Но чтобы вызвать его напрямую, не нужно virtual функции.

2

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