С ++ должен удалить ссылки? - PullRequest
9 голосов
/ 20 июня 2010

в следующем коде:

class x
{
private:
 someRef& m_ref;

public:
 x(someRef& someRef):m_ref(someRef)
{ 
}

мне нужно сделать:

~x()
{
  delete m_ref;
}

который, кстати, не работает без получения указателя ...

В основном я спрашиваю: Нужно ли вызывать деструктор для ссылочного элемента?

Ответы [ 5 ]

16 голосов
/ 20 июня 2010

номер

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

6 голосов
/ 20 июня 2010

Я не думаю, что кто-то на самом деле, строго говоря, удаляет даже указатели.То, что вы удаляете, это динамически размещаемые объекты (или массивы объектов), для которых указатель является дескриптором.Если объект происходит от вызова new , и этот класс отвечает за очистку после этого объекта, то вы вызываете delete .

Это техническиВозможно, что ссылка ссылается на динамически размещенный объект:

int main()
{
    //in principle a reference can also refer to a dynamically allocated object
    x var(*new someRef); 
}

//and if that is the intended usage:
x::~x()
{
  delete &m_ref;
}

Однако это будет невероятно плохой стиль.По соглашению, «владеющий» дескриптор динамически размещаемого объекта не должен быть ссылкой.

3 голосов
/ 20 июня 2010

Я хочу прояснить некоторые заблуждения, которые у вас, по-видимому, выходят за рамки вашего вопроса:

Когда вызывается деструктор класса, также вызываются все деструкторы его членов.

Вызов delete - это не то же самое, что вызов деструктора. delete явно вызывает деструктор, а также вызывает operator delete в месте расположения объектов, это вещь из двух частей.

3 голосов
/ 20 июня 2010

Нет. Вы можете удалять только указатели, но не ссылки, и даже тогда вы должны удалять только те объекты, которые были выделены с помощью оператора new. И тогда вы должны обязательно удалить их только один раз. Вот случай, когда вам нужно будет использовать delete в вашем деструкторе:

class x
{
private:
 someObj* m_ptr;

public:
 x():m_ptr(new someObj())
{ 
}

 ~x()
{
  delete m_ptr;
}

Но в целом лучше избегать даже этого и использовать вместо этого умные указатели.

1 голос
/ 13 августа 2011

Для небольшого дополнительного уточнения я хочу предложить следующее:

int *pi = new int;

//int& ir = pi; // can't do
                // this a reference to the pointer but it is an error
                // because or the type difference int& vs int* and
                // static_cast won't help.  reinterpret_cast would allow
                // the assignment to take place but not help the 'delete ir'

int& ir = *pi;  // this is OK - a reference to what the pointer points to.
                // In other words, the the address of the int on the heap.

//delete ir;    // can't do, it is a reference and you can't delete non-pointers.

delete &ir;     // this works but it is still not "deleting a reference".
                // The reference 'ir' is another name for the heap-based int.
                // So, &ir is the address of that int, essentially a pointer.
                // It is a pointer that is being used by delete, not a reference.
...