Почему адреса двух разных объектов должны быть разными? - PullRequest
7 голосов
/ 11 февраля 2011

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

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

Итак ... $ SUBJ.

Ответы [ 5 ]

6 голосов
/ 11 февраля 2011

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

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!

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

5 голосов
/ 11 февраля 2011

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

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

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

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

delete object1;

что будет delete d, если они оба будут иметь один и тот же адрес?

3 голосов
/ 11 февраля 2011

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

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

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

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

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

1 голос
/ 11 февраля 2011

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

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

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

0 голосов
/ 11 февраля 2011

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

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

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

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