【问题标题】:Address of object in c++ functionc++函数中对象的地址
【发布时间】:2012-02-22 20:42:59
【问题描述】:

问题是如何在不触及 this 的情况下获取指向类内部方法的 self 的指针:

class Foo
{
   int a, b, c;
   void Print();
};

这种方式在通用编译器中我可以参考第一个数据字段:

void Foo::Print()
{
   cout << &a; // == this
}

但是当只存在函数时,有没有什么方法可以在没有数据成员的情况下做到这一点?

class Foo2
{
   void Print();
};

附言甚至不要问我为什么需要这个:)

【问题讨论】:

  • @JanKoester:或者更确切地说,this 指向的对象。 (毕竟,this 是一个指针,而不是一个对象 :))
  • 您仍在隐式使用this。你的意思是你的源代码中不能有令牌this 吗? th##is 怎么样?
  • @BenVoigt 这只是关于内存中类结构的理论:)
  • @Ockonal:不,编译器会将非静态成员的任何非限定用法转换为对this 的引用。如果您不相信我,请尝试在 lambda 中使用非静态成员而不捕获 this
  • @BenVoigt 你不理解我。

标签: c++ class memory pointers


【解决方案1】:

对于至少有一个数据成员的 POD 类,类类型对象的地址与其第一个数据成员的地址相同。这是因为在 POD 结构类型的第一个数据成员之前不能有未命名的填充字节。 [在 C++11 中,规则有点不同;我相信这适用于所有 标准布局 类类型。但是,我对规则并不完全熟悉。]

对于任何其他类类型,没有办法做到这一点。

【讨论】:

  • 我认为您正在寻找的规则是 9.2p20。 “指向标准布局结构对象的指针,使用reinterpret_cast 进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。”
  • @BenVoigt:是的,这就是我想要的,谢谢。我已经没有 C++ 标准的副本了。我发现没有它可以帮助我专注于工作,而不会因为在 Stack Overflow 上回答语言律师问题而分心:-)
【解决方案2】:
class Foo2
{
   void Print();
};

#define OBJADDR(x) (th##x##s)

void Foo2::Print()
{
    int i; // red herring, but the name MUST be `i`
    std::cout << OBJADDR(i);
    i; // to get rid of compiler warning about unused local variable
};

【讨论】:

  • iPrint 调用中是什么?
  • @Ockonal:你更喜欢那个版本吗?
  • 哈!非常有趣。你会来雷德蒙德参加 MVP 峰会吗?
  • @James:我希望,但没有时间。但我已经下定决心明年一定要去(如果我在四月续约的话)。
【解决方案3】:

如果您的类没有数据成员,那么从技术上讲,该类的实例甚至都不存在。仅为方便起见,它们的大小必须至少为 1 字节,并具有唯一的 this 指针。如果您从一个没有数据成员的类继承,它的大小将折叠为 0 并消失。

所以不,没有任何方法可以在不使用 this 指针的情况下获取 this 指针。一个不太实用的 C++ 版本甚至没有 this 指向这些对象的指针,因为它们的大小为 0。

【讨论】:

    【解决方案4】:

    您可以可能使用offsetof 宏破解它

    void Foo::Print()
    {
       cout << static_cast<char *>(&a) - offsetof(Foo, a);
    }
    

    如果您不能安全地假设&amp;a 是开始。

    那么……你为什么需要这样做?

    【讨论】:

    • 它是 Foo 的数据成员,我们显然忽略了它与 this-&gt;a 相同的事实
    猜你喜欢
    • 1970-01-01
    • 2018-08-25
    • 2015-04-18
    • 2018-07-26
    • 1970-01-01
    • 2016-04-03
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多