В зависимости от того, что вы имеете в виду. Каждый раз, когда у вас есть указатель, можно указать , чтобы позвонить delete
.
И если у вас есть ссылка, вы можете взять адрес этого, который дает вам указатель
Во всяком случае, если у вас есть этот класс, например:
class X {
int getByVal() { return i; } // returns a copy of i
int& getByRef() { return i; } // returns a reference to i
private:
int i;
};
тогда я, как пользователь вашего класса, не имеет Очевидный способ удалить ваши данные. я могу сделать следующее:
X x;
int j = x.getByVal();
int& k = x.getByRef();
j = 42; // doesn't affect x.i because we returned a copy
k = 42; // sets x.i to 42, because k is a reference
И нет никакого очевидного способа для меня, чтобы удалить члена класса. Конечно, я мог сделать это:
delete &j;
delete &k;
(и, конечно же, ни один из них будет делать ничего значимого, но они будут компилировать), но я бы не сделать это случайно. Если вы не вернете указатель, довольно ясно, что я не должен брать на себя ответственность за данные.
«Защитите свой код от Мерфи, а не Макиавелли», как правило, хорошее эмпирическое правило. Вы не можете помешать людям разрушить ваш код , если они попробуют. Все, о чем вы должны беспокоиться, мешает им делать это случайно.
Редактировать
В ответ на ваш комментарий под вопросом:
как я уже говорил, я учусь ... Копия сделать думают, что вызываемое должен освободить память возвращения переменного, это больше неприятностей для вызываемого (даже подумал, что это я = р), поэтому я не говорил о концепциях, а о легкости письма ... и снова, я новичок в этой памяти. Я развивался в C#, PHP и т. Д. Я давно развивался в C, когда учился с CircleMUD
Нет, копии не нужно удалять вручную. Локальные переменные автоматически удаляются, когда они выходят за рамки. Таким образом, в приведенном выше примере j
является копией члена класса i
. Когда функция вызова возвращается, j
будет автоматически удалена.
Надеюсь, что это поможет. Правила переменной жизненного цикла в C++ не очень сложны, но крайне важно, чтобы их правильно, так как от них зависит много кода.
void foo()
{
int i = 0; // allocate a local (on the stack) int, and initialize it to 0
int* p = new int(1); // allocate an int on the heap, and initialize it to 1
int j = i; // create a *copy* of i. Now we have two ints on the stack
int k = *p; // create a copy of the int pointed to by p. k is also on the stack, so even though it was copied from a heap-allocated variable, k does not have to be manually deleted
int* q = p; // create a copy of p. q is not a separate pointer, which points to the *same* heap-allocated integer.
}
в приведенном выше примере, все копии автоматически очищаются, когда foo
возвращается. Единственное, что нам нужно сделать вручную - удалить целое число, выделенное в куче. Оба указывают на него p
и q
, но мы должны только удалить объект один раз. Но i
, j
, k
, p
и q
- все локальные переменные, объявленные в стеке. Каждый из них очищается, когда функция возвращается. Для примитивных типов (например, int
s, а также указателей) ничего не должно произойти (у них нет деструкторов). Когда они выходят из сферы действия, они просто исчезают, даже если они указывают на что-то важное, например, на выделенный кучей объект, такой как наше целое число.
Для объектов, отличных от POD, когда они выходят из сферы действия, их деструкторы называются, поэтому они тоже хорошо очищаются, все сами по себе. Таким образом, даже если бы мы использовали более сложный тип, чем int
, вышеизложенное было бы прекрасно. Мы все еще можем копировать объекты не-POD и передавать их по значению.
Я надеюсь, что это поможет немного разобраться.
Почему вы не можете вернуть копию вместо ссылки? – JRL
Является ли возврат по стоимости опцией? – coelhudo
Я могу, но это не лучший ответ, я думаю. Я думаю, что буду использовать boost или что-то еще, прежде чем полагаться на копии – Jonathan