基类成员函数是否可以直接访问子类成员函数?
我发现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);
儿童类宣言&amp;实现:
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 :(得分:2)
基类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
;
答案 1 :(得分: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)
,至少在调试模式下,以进行调试。或者,您可以声明Base类的构造函数,析构函数protected
,以防止创建不完整的对象,或者尝试在基础不是多态时销毁派生对象
但是,上述代码在现实世界中并不常见。存在其他更高级的技术,如CRTP,它也使用static_cast
并提供没有virtual
函数的静态多态性。
这个答案可能不是你想要的。它只表明可以在基类中调用派生类成员,即使它根本没有在base中定义。但是要在没有任何演员的情况下直接调用它,您仍然需要virtual
个函数。