Почему адреса двух разных объектов должны быть разными?

Я читал об этом, что размер объекта должен быть не менее 1 байта ( C++: каков размер объекта пустого класса?) И что плохого в том, что два пустых объекта имеют один и тот же адрес? В конце концов, мы можем иметь два указателя на один и тот же объект.

Поиск в Google говорит мне, что есть что-то в правиле fundemantal идентификации объекта, но я не могу найти более подробную информацию об этом.

Итак... $SUBJ.

5 ответов

Решение

Наличие двух объектов по одному и тому же адресу будет означать, что не будет возможности различить эти два объекта при обращении к ним с помощью указателей. Например, в следующем коде:

EmptyClass o1;
EmptyClass o2;

EmptyClass * po = &o;
po->foo();

Следует ли вызывать метод foo o1 или же o2?

Можно утверждать, что, поскольку эти объекты не имеют данных и виртуальных методов (в противном случае они имели бы ненулевой размер), не имеет значения, в каком экземпляре вызывается метод. Однако это становится более важным, когда мы хотим проверить, равны ли два объекта (т. Е. Совпадают ли они):

template < typename T >
bool isSame( T const & t1, T const & t2 )
{
    return &t1 == &t2;
}

EmptyClass o1; // one object and...
EmptyClass o2; // ...a distinct object...

assert( ! isSame( o1, o2 ) ); // ...should not be one and same object!

Для более конкретного примера, давайте предположим, что я хочу связать некоторые объекты (я бы сказал, сущности) с некоторыми значениями, скажем, в ассоциативном контейнере:

Person you;
Person me;

// You and I are two different persons
// (unless I have some dissociative identity disorder!)
// Person is a class with entity semantics (there is only one 'me', I can't make
// a copy of myself like I would do with integers or strings)

std::map< Person *, std::string > personToName;

personToName[&you] = "Andrew_Lvov";
personToName[&me]  = "Luc Touraille";
// Oh, bother! The program confused us to be the same person, so now you and I
// have the same name!

Так что да, все сводится к идентичности объектов: если объектам разрешено быть пустыми, они могут быть лишены своей идентичности, что просто не допускается языком (к счастью).

Каждый объект должен занимать отдельное хранилище, иначе вы не сможете освободить один объект, не освободив другие, которые совместно используют хранилище с ним.

Предположим, у вас есть два разных объекта по одному адресу:

Type* object1 = new Type(); //first object
Type* object2 = new Type(); //second object

и они оказываются по тем же адресам, то вы

delete object1;

что будет deleteг если они оба имеют одинаковый адрес?

В C++ есть (среди прочего) правило, согласно которому указатели на объекты сравниваются равными тогда и только тогда, когда указатели ссылаются на один и тот же объект. По предложенному вами сценарию это больше не будет правдой.

Там также довольно много кода, который просто предполагает sizeof также даст строго положительный результат. Например, довольно много кода использует такие вещи, как:

#define elements(array) ((sizeof(array)/sizeof(array[0]))

Для объектов с нулевым размером это приведет к 0/0, который математически не определен.

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

Когда у вас есть два указателя на один и тот же объект, вы можете использовать любой из них для управления объектом. Результат = вы можете получить доступ к объекту.

Однако, если у вас есть два объекта по одному адресу, как бы вы различали их в памяти? Если бы у вас был указатель на этот адрес, как бы вы узнали, на какой объект указывал ваш указатель?

Отсюда и необходимость разных адресов для каждого объекта, даже если они пусты.

Попробуйте аналогию.

Если у вас есть две машины, и вы пытаетесь занять их в одном и том же физическом пространстве, вы столкнетесь с аварией.

Если у вас есть два объекта и вы пытаетесь занять их в одном и том же пространстве памяти, у вас также будет сбой.

Другие вопросы по тегам