Гарантировано ли это значение для C ++?

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

В приведенном ниже коде equalPointer гарантированно вернет истину? Есть ли случаи, когда он может вернуть false (например, при рассмотрении множественного наследования)?

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

person CiscoIPPhone    schedule 02.12.2010    source источник


Ответы (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 есть виртуальные методы)

person Matthieu M.    schedule 03.12.2010

С рассматриваемым кодом? да.

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

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

person Edward Strange    schedule 02.12.2010
comment
Хм. Что происходит, когда функция определяется как template <typename T> bool equalPointer(T const* f) и вызывается как f.equalPointer(&f)? Сейчас f == this гарантировано? Коррекция смещения тогда не должна происходить, верно? - person Konrad Rudolph; 03.12.2010

Да, это.

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

person peoro    schedule 02.12.2010