Область объекта при передаче по ссылкам и по указателям

Рассмотрим следующий простой код.

    struct test
{
test(int n):numelements(n){ arr = new int[numelements] }

int numelements;
int* arr;

~test()
{
delete[]  arr;
}
}

void foo_ref(test& x,n)
{
// set first n elements of the array x.arr to random numbers
}

void foo_ptr(test* x,n)
{
// set first n elements of the array x->arr to random numbers
}

int main(void)
{
test mystruct(1000000);
foo_ref(mystruct,20);
// foo_ptr(&mystruct,20);return 0;
}

В приведенном выше коде, foo_ref а также foo_ptr выполнять точно такие же операции на
объект, к которому он относится, а именно mystruct, Однако foo_ref передает объект по ссылке
и foo_ptr с помощью указателей.

В обоих случаях где вызывается деструктор объекта? Я знаю, что стандартный ответ на этот вопрос всегда таков: «когда заканчивается предмет»

Но рассмотрим случай передачи по ссылке. В теле foo_ref
mystruct имеет область действия этой функции. Так не будет ли деструктор объекта вызываться в конце функции foo_ref?

Может быть, мое замешательство связано с пониманием объема чего-либо.
Пожалуйста, дайте мне знать, где я ошибаюсь в своих рассуждениях.

1

Решение

Я не вижу const ссылки здесь, поэтому ответ «ничем не отличается в жизни объекта между ссылками и указателями».

const ссылки, привязанные к временным выражениям, имеют специальное правило, продлевающее время жизни временного объекта, но это не относится к вашему коду.

Ваше замешательство, вероятно, проистекает из заявление сделано в очень популярном FAQ, это происходит по принципу «ссылка — это объект, на который есть ссылка». Как видите, это не так. Ссылка отделена от объекта, на который она ссылается, у каждого свое время жизни (и очень редко можно увидеть, что это сделано правильно, но даже допустимо, чтобы время жизни ссылки увеличивалось дольше, чем время жизни объекта)

3

Другие решения

foo_ref будет иметь параметр, и это параметр, который будет иметь область действия функции. Будь то указатель или ссылка, не повлияет на удаление mystruct.

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

1

В примере кода деструктор для mystruct называется в конце main,

указатели Когда указатель выпадает из области видимости, с указанным объектом ничего не происходит. Время жизни объекта остается тем, чем оно было бы, если бы указатель никогда не существовал. Есть, конечно, важная деталь: объекты, созданные new/new[] существуют, пока они не deleteд /delete[]г, и память, выделенная malloc существует до freeд.

Рекомендации Ссылка — это не что иное, как дополнительное имя для существующего объекта. За исключением const ссылка, указывающая на временный объект, время жизни ссылки не влияет на время существования объекта, на который ссылаются; деструктор вызывается, когда этот объект обычно выходит из области видимости ( const ссылка на временный объект поддерживает временную работу до const ссылка выходит за рамки).

Использование термина «объект» является упрощением, указатель или ссылка действительно указывает на память; он никак не «отслеживает» реальный объект. Например, можно уничтожить объект, на который указывает указатель до того, как указатель выйдет из области видимости, или уничтожить объект, на который имеется ссылка, до того, как ссылка выпадет из области видимости. Эти недействительные указатели / ссылки называются «висячие указатели» и «висячие ссылки» соответственно:

int* i = new int(5);
int& j = *i;
delete i;

// i is now a dangling pointer, and j is now a dangling reference
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector