C++中的this指针是否有保证?

8
考虑一个没有重载其 & 运算符的类 Foo,从该类的 & 运算符获得的地址是否保证与其 this 指针具有相同的值?
在下面的代码中,equalPointer 是否保证返回 true? 是否存在可能返回 false 的情况(例如考虑多重继承)?
class Foo
{
  bool equalPointer(const Foo * f} { return f==this; }
}
Foo f;
f.equalPointer(&f);
3个回答

3
问题在于内存布局。标准并没有对内存布局做出太多保证,特别是它不能保证派生类和基类之间不存在偏移量...
例如:
class Foo: public boost::noncopyable
{
public:
  virtual ~Foo();
};

因为boost::noncopyable没有virtual方法,在gcc中,(void*)(Foo*)&f(void*)(boost::noncopyable*)&f将具有不同的值。
但在实践中,这并不重要,因为编译器会执行必要的调整。也就是说,如果只比较Foo*,那么你应该没问题...
...除非多重继承会破坏这一点,如果你的层次结构中有几个Foo子对象。
另一方面,你应该处于以下两种情况之一:
  • 要么没有层次结构(没有虚拟),那么你可以直接比较对象的地址
  • 或者存在层次结构(和虚拟方法),你使用dynamic_cast<void*>(&f)来获取完整对象的地址。
因此,作为一个模板方法,它应该是这样的:
template <typename T, typename U>
bool have_same_dynamic_location(T const& t, U const& u)
{
  return dynamic_cast<void*>(&t) == dynamic_cast<void*>(&u);
}

(仅在T和U都有虚拟方法时有效)

2

这段代码是如此的吗?是的。

是否存在构造,使得这不那么正确?也是的。

但是,指向类X实例的指针始终等于类X内的'this'指针。同样的情况并不适用于它的基类或派生类。


1
当函数定义为 template <typename T> bool equalPointer(T const* f) 并被调用为 f.equalPointer(&f) 时会发生什么呢?现在 f == this 能够保证吗?偏移校正不应该发生,对吧? - Konrad Rudolph

2

是的,没错。

f 的指针是相同的,并且被传递给了 f::equalPointer...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接