gpt4 book ai didi

c++ - 向上转型到父类(super class)或接口(interface)?

转载 作者:行者123 更新时间:2023-11-28 08:01:05 28 4
gpt4 key购买 nike

我正在尝试确认我已经在实践中使用的东西背后的理论。完整的设置有点扭曲,因为功能在不同的 dll 之间拆分,但我将尝试描述这种情况:

class __declspec( dllexport ) BaseClass
/** This class' definition is available to everything,
* via .h file, .dll and .lib. */
{
protected:
std::string name;

public:
std::string GetName();
/** This is implemented in BaseClass, and just returns this->name. */
}

class DerivedClass: public BaseClass
/** This class is created within the executable, but is not 'visible' to other
* dlls - either through .h files, .lib, or anything else. */
{
public:
DerivedClass();
/** This sets this->name based on its own propertied. */
}

这种向上转换有效,但它需要完全访问 DerivedClass 的定义:

void* pointer;
DerivedClass* derived_pointer = reinterpret_class<DerivedClass*>(pointer);
BaseClass* base_pointer = dynamic_cast<BaseClass*>(derived_pointer);
base_pointer->GetName();

但是,以下内容不起作用:

void* pointer;
BaseClass* base_pointer = reinterpret_class<BaseClass*>(pointer);
base_pointer->GetName();

为了解决这个问题,我实现了一个接口(interface):

class __declspec( dllexport ) IBaseClass
/** Fully virtual 'interface' class, in same file as BaseClass. */
{
public:
virtual std::string GetName() = 0;
}

class __declspec( dllexport ) BaseClass: public IBaseClass
/** This class' definition is available to
* everything, via .h file, .dll and .lib. */
{
protected:
std::string name;

public:
std::string GetName();
/** This is implemented in BaseClass, and just returns this->name. */
}

class DerivedClass: public BaseClass
/** This class is created within the executable, but is not 'visible'
* to other dlls - either through .h files, .lib, or anything else. */
{
public:
DerivedClass();
/** This sets this->name based on its own propertied. */
}

现在下面的代码可以工作了:

void* pointer;
IBaseClass* ibase_pointer = reinterpret_class<IBaseClass*>(pointer);
ibase_pointer->GetName();

我模糊地记得有人告诉我转换为完全虚拟的类是一种特殊情况 - 但我不记得为什么,也不知道在网上找到任何关于它的信息。

请帮助我 - 为什么我的代码可以工作?!

最佳答案

这完全依赖类布局,类布局是实现定义的,不能依赖。专门针对 MSVC,类布局的一个很好的介绍是 http://www.openrce.org/articles/full_view/23值得一提的是,您可以使用 /d1reportSingleClassLayout 标志请求类布局。

在您的情况下,由于第一个 BaseClass 没有虚拟成员,它将被放置在 DerivedClass 中的一个非指定位置。我猜 DerivedClass 有一些虚拟成员,否则我希望 BaseClass 位于 DerivedClass 的开头reinterpret_cast 开始工作。如果它有虚拟成员,您将拥有:

+--------------------+
|DerivedClass vtable |
|BaseClass::name |
|DerivedClass members|

通过添加接口(interface) IBaseClass 没有任何改变; DerivedClass 仍然布局为:

+--------------------+
|DerivedClass vtable |
|BaseClass::name |
|DerivedClass members|

但是 DerivedClass vtable 以 IBaseClass vtable 开始:

+---------------------+
|IBaseClass::GetName |
|DerivedClass virtuals|

因此通过 DerivedClass vtable 进行调用是可行的。

关于c++ - 向上转型到父类(super class)或接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11455134/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com