c++ - C++ 是否可以编排基类相对于其派生类的偏移量?
问题描述
考虑以下“黑匣子”,
template<std::size_t offset, typename T>
class BlackBox;
其中必须具有以下功能:
class SomeClass; // This class has a virtual destructor
// and a default constructor.
constexpr std::size_t offset = alignof(SomeClass);
auto bb = new BlackBox<offset, SomeClass>;
SomeClass* ptr = bb;
assert((char*)ptr - (char*)bb == offset); // OK(!)
delete ptr; // OK - destructs and deletes bb correctly.
这里offset
始终是 的非负倍数alignof(SomeClass)
,但为了这个问题,您可能会假设它恰好是 1 倍alignof(SomeClass)
。
此外,您可以假设alignof(SomeClass) <= alignof(std::max_align_t)
.
如果在(任何)C++ 标准中都不可能,那么您可以假设使用的编译器是最新版本的 g++。
我很清楚这属于“肮脏的编程”;不过我有点“需要它”。问题是是否有可能(以及如何)使用任何可能的黑客攻击。
我尝试了以下方法,但这不起作用:
template<std::size_t offset, typename T>
struct Offset {
typename std::aligned_storage<offset, alignof(T)>::type m_offset;
};
template<std::size_t offset, typename T>
class BlackBox : Offset<offset, T>, public T {
static_assert(offset % alignof(T) == 0, "");
using T::T;
};
这里的问题是,不能保证在多继承的情况下基类如何在内存中排序,并且一旦 T 有一个虚拟表,它就会首先放在内存中(通过 g++) - 立即减少计算的偏移量在断言为 0。
解决方案
推荐阅读
- c++ - 如何隐藏主工具栏
- google-apps-script - 其可能的 Google 表单脚本每天上午 00:01 至下午 12:00 自动打开和关闭
- angular - 错误:无法匹配任何路由。网址段
- c++ - 从布局中删除一个小部件并用另一个小部件填充它的空间
- azure - 我可以使用已删除集群的 API 服务器地址和 IP 地址删除并重新创建 AKS 集群吗
- javascript - Gulp concat 输出带有导入语句的文件以及具有相同标识符的导出?
- reactjs - React native animation.reset 不会重置动画
- dialogflow-cx - DialogFlow CX 不允许在条目执行中引用表单参数?
- java - java中的Oauth2令牌处理库
- sql - Oracle 视图中的多个列使用返回对象类型的相同函数