【问题标题】:C++, statically detect base classes with differing addresses?C ++,静态检测具有不同地址的基类?
【发布时间】:2009-07-15 14:09:42
【问题描述】:

如果我有一个具有多个基的派生类,则每个基的每个 this 指针都将不同于派生对象的 this 指针,除了一个。给定继承层次结构中的两种类型,我想在编译时检测它们是否共享相同的 this 指针。像这样的东西应该可以工作,但不能:

BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);

因为它需要是一个“整数常量表达式”,并且根据标准只允许整数转换(这很愚蠢,因为如果没有使用虚拟继承,它们只需要编译时间信息)。尝试将结果作为整数模板参数传递时也会出现同样的问题。

我能做的最好的事情是在启动时检查,但我需要在编译期间的信息(让一些深入的模板黑客工作)。

【问题讨论】:

  • “如果没有使用虚拟继承,它们只需要编译时间信息”在大多数/所有实现中。该标准允许任何非 POD 转换使用运行时信息。

标签: c++ memory templates multiple-inheritance static-cast


【解决方案1】:

我不知道如何检查您不想要的内容,但请注意,在存在空基类的情况下您的假设是错误的。只要它们的类型不同,它们中的任意数量都可以从对象的开始处共享相同的偏移量。

【讨论】:

  • 多考虑一下你的问题——假设你的问题是关于基类的偏移量而不是指针——我会认为 offsetof 返回一个常量整数表达式,所以应该能够检查您是否可以将自己限制在 POD 中。但是如果我将 offsetof 与派生类一起使用,g++ 会抱怨,我想知道我错过了什么。
  • @AProgrammer:您缺少的是什么,任何派生类根据定义都是非 POD?因此 OP 不能只使用 POD 类。
  • 糟糕,我经常查看当前草案(其中使用 offsetof 的先决条件标准布局可以有非虚拟基类)。
【解决方案2】:

我正在尝试解决这个完全相同的问题。如果您知道基类布局开头的成员变量是什么,我有一个有效的实现。例如。如果成员变量“x”存在于每个类的开头,则以下代码将用于从派生类布局中产生特定基类布局的字节偏移量:offsetof(derived, base2::x)。

如果是:
struct base1 { char x[16]; };
struct base2 { int x; };
struct derived : public base1, public base2 { int x; };
static const int my_constant = offsetof(derived, base2::x);

编译器会在我的架构 (x86_64) 上正确地将“16”分配给 my_constant。

当您不知道基类布局开头的成员变量是什么时,困难在于获得“16”。

【讨论】:

    【解决方案3】:

    我什至不确定这个偏移量是否是一个常数。您是否有其他建议的规范措辞?

    我同意非常量偏移量在没有虚拟继承的情况下很难实现,而且启动毫无意义。这不是重点。

    【讨论】:

      【解决方案4】:

      类没有 this 指针 - 类的实例有,而且每个实例的指针都不同,无论它们是如何派生的。

      【讨论】:

      • 然而,他正在创建一个假对象指针,并尝试使用在编译时做出的基类偏移假设来推断它是否具有基类。他不需要一个真实的对象 - 但是我认为它太依赖于实现了。
      【解决方案5】:

      【讨论】:

      • 即使这并不完美,看看他们的实现可能会对您有所帮助:)
      • 不幸的是,我需要实际的偏移量。他们的实现可能仍然对我有帮助......一旦我理解它;)它非常密集。
      【解决方案6】:

      我没有意识到编译器会在运行时插入此检查,但您的基本假设并不完全正确。不过可能不是您关心的方式:如果您碰巧从多个具有sizeof(base class)==0 的基类继承,编译器可以使用空基类优化。这将导致(base class *)(derived *)1==at least one other base class

      就像我说的,这可能不是你真正需要关心的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多