C ++向下转换以撤消函数覆盖
C++ downcast to undo function overriding
在下面的示例中,我有一个基类和一个派生类 class,两者几乎相同,但派生类覆盖了一个函数。基础 class 有一个很大的成员,所以我想通过只创建派生的 class 对象来节省内存使用,然后将其转换为基础对象,因此将调用非覆盖函数。
但是,一旦将转换后的对象传递到 InitBuffer() 中,该对象就会显示为原始对象 class。我想这并没有让我感到惊讶(因为它实际上只是将内存指针传递给对象)但我不知道如何 "fully cast" 以便它按我想要的方式工作。这可能吗?
class BaseClass
{
public:
virtual void InitBuffer(void) { /* ...do base stuff... */ }
private:
char BigBuffer[1024*1024];
};
class DerivedClass : public BaseClass
{
public:
virtual void InitBuffer(void) { /* ...do derived stuff... */ }
};
void DoSomething(BaseClass &MyObject)
{
MyObject.InitBuffer();
}
void NotWorkingFunctionality(void)
{
DerivedClass DerivedObj; /* Reuse this object for both cases */
volatile bool IsFoo = true;
if (IsFoo)
/* I want this to end up calling BaseClass's InitBuffer */
DoSomething(dynamic_cast<BaseClass &>(DerivedObj)); /* Doesn't work :( */
else
/* I want this to end up calling DerivedClass's InitBuffer */
DoSomething(DerivedObj); /* Works great! */
}
void DesiredFunctionality(void)
{
DerivedClass DerivedObj;
BaseClass BaseObj; /* Problem: Twice the memory usage that I want!! */
volatile bool IsFoo = true;
if (IsFoo)
DoSomething(BaseObj); /* Works great! */
else
DoSomething(DerivedObj); /* Works great! */
}
在 C++ 中,virtual
方法及其覆盖实现为 vtables。 vtable 实际上是一个 table 的函数指针,用于每个虚函数。这允许 subclasses 将它们的方法指向其他实现。
指针或引用转换不会更改 vtable 的内容。调用 InitBuffer
被翻译为对任何当前实例实现 InitBuffer
的虚函数调用。
你能做什么?如果您在外部调用它,如您的示例所示,请参阅 the answer to this question:
myObject.BaseClass::InitBuffer();
在子 class 方法中,您只需执行以下操作:
BaseClass::InitBuffer();
在下面的示例中,我有一个基类和一个派生类 class,两者几乎相同,但派生类覆盖了一个函数。基础 class 有一个很大的成员,所以我想通过只创建派生的 class 对象来节省内存使用,然后将其转换为基础对象,因此将调用非覆盖函数。
但是,一旦将转换后的对象传递到 InitBuffer() 中,该对象就会显示为原始对象 class。我想这并没有让我感到惊讶(因为它实际上只是将内存指针传递给对象)但我不知道如何 "fully cast" 以便它按我想要的方式工作。这可能吗?
class BaseClass
{
public:
virtual void InitBuffer(void) { /* ...do base stuff... */ }
private:
char BigBuffer[1024*1024];
};
class DerivedClass : public BaseClass
{
public:
virtual void InitBuffer(void) { /* ...do derived stuff... */ }
};
void DoSomething(BaseClass &MyObject)
{
MyObject.InitBuffer();
}
void NotWorkingFunctionality(void)
{
DerivedClass DerivedObj; /* Reuse this object for both cases */
volatile bool IsFoo = true;
if (IsFoo)
/* I want this to end up calling BaseClass's InitBuffer */
DoSomething(dynamic_cast<BaseClass &>(DerivedObj)); /* Doesn't work :( */
else
/* I want this to end up calling DerivedClass's InitBuffer */
DoSomething(DerivedObj); /* Works great! */
}
void DesiredFunctionality(void)
{
DerivedClass DerivedObj;
BaseClass BaseObj; /* Problem: Twice the memory usage that I want!! */
volatile bool IsFoo = true;
if (IsFoo)
DoSomething(BaseObj); /* Works great! */
else
DoSomething(DerivedObj); /* Works great! */
}
在 C++ 中,virtual
方法及其覆盖实现为 vtables。 vtable 实际上是一个 table 的函数指针,用于每个虚函数。这允许 subclasses 将它们的方法指向其他实现。
指针或引用转换不会更改 vtable 的内容。调用 InitBuffer
被翻译为对任何当前实例实现 InitBuffer
的虚函数调用。
你能做什么?如果您在外部调用它,如您的示例所示,请参阅 the answer to this question:
myObject.BaseClass::InitBuffer();
在子 class 方法中,您只需执行以下操作:
BaseClass::InitBuffer();