Гарантируется ли это в C ++? - PullRequest
8 голосов
/ 03 декабря 2010

Предположим, у меня есть класс Foo (у которого не перегружен оператор &). Гарантируется, что адрес, полученный от оператора & этого класса, будет иметь то же значение, что и указатель this?приведенный ниже код равен equPointer гарантированно вернуть true?Есть ли случаи, когда он мог вернуть false (например, при рассмотрении множественного наследования)?

class Foo
{
  bool equalPointer(const Foo * f} { return f==this; }
}
Foo f;
f.equalPointer(&f);

Ответы [ 3 ]

3 голосов
/ 03 декабря 2010

Проблема связана с макетом памяти. Стандарт не гарантирует многого о расположении памяти, в частности он не гарантирует, что не существует смещения между производным и базовым классом ...

Например:

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 голосов
/ 03 декабря 2010

Да, это так.

Указатель f такой же, и он передается f::equalPointer ...

2 голосов
/ 03 декабря 2010

С указанным кодом?Да.

Существуют ли конструкции, в которых это не так верно?Также да.

Но да, указатель на экземпляр класса X всегда будет равен указателю 'this' в классе X. Этого нельзя сказать о его базовых классах или производных классах.

...