2015-10-12 3 views
0

Скажем, у меня есть класс, какДолжен ли я вручную сбросить shared_ptrs в своих собственных деструкторах?

class A { 
public: // I know, I know... 
    shared_ptr<string> aString; 
}; 

я должен иметь деструктор, как

~A() { 
    aString.reset(); 
} 

для обеспечения того, чтобы право собственности правильно reliquished? Я сделал несколько тестов, и мне кажется, что мне не нужно - то есть, когда экземпляр A выходит из области видимости или удаляется (или сбрасывается, если я ссылаюсь на него через shared_ptr), строка также удаляется (Я сыграл с более сложным примером, чтобы подтвердить это). Однако это может быть реализация, специфичная для компилятора, который я использую (clang-700.0.72).

Мой вопрос: всегда ли это так, или лучше явно сбросить эти экземпляры, как если бы я удалил любой другой немой указатель?

+0

Вы должны рассмотреть, что вам нужно в копии ctor и присвоении. По умолчанию вы получите второй общий указатель на один и тот же объект с увеличенным счетчиком акций (мелкая копия). Если вам нужна глубокая копия, вы должны сами ее организовать. (Необычно, потому что все дело в shared_ptr заключается в совместном использовании, а глубокая копия означает отсутствие совместного использования). – MSalters

+0

Да, если мне нужно поделиться собственностью - краткосрочной или долгосрочной - я бы ожидал получить все подсчеты использования, поднятые одним. В конкретном случае, вызвавшем мой вопрос, у меня есть класс, который, скорее всего, будет иметь только одного владельца, но ему необходимо твердо придерживаться этого члена, что также означает, что указатель в моем реальном случае никогда не будет использоваться вне класса, и даже если это произойдет, оно будет по крайней мере равно + 1'd от случайных удалений (что, как мне известно, вряд ли произойдет, потому что это не библиотечный код :) – Morpheu5

+0

Не лучше ли вы использовать 'std :: unique_ptr' в этом случае и раздача ссылок? Если кто-нибудь собирается называть «delete» на ссылке, я считаю, что вы имеете право сделать имитацию Линуса Торвальдса. – MSalters

ответ

4

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

Деструктор shared_ptr автоматически уменьшит счетчик ссылок, и если он достигнет 0, вызывается дебетер.

Если вы не предоставите деструктор, по умолчанию будет сгенерирован:

§ 12.4.4 Если класс не имеет пользовательского объявленная деструктор деструктор неявно объявлен дефолт

Уничтожение вашего класса гарантирует уничтожение членов.

§ 12.4.8 После выполнения тела деструктора и уничтожить любые автоматические объекты, выделенные в организме, деструктор для класса X вызывает деструкторы для прямых, не вариантных нестатических элементов данных иксов (. ..)

Который в свою очередь, для shared_ptr означает:

§ 20.8.2.2.2.1

~shared_ptr();

Эффекты:

  • Если * это пустая или доли собственности с другим shared_ptr экземпляра (use_count()> 1), нет никаких побочных эффектов.

  • В противном случае, если * этому принадлежит объект p и deleter d, d (p).

  • В противном случае * это принадлежит указателю p и вызывается p.

Такое поведение является хорошо резюмировать The Rule Of Zero.

+3

Является ли имя вызывающим, а затем редактирует ваше сообщение, чтобы включить принятую точку в форму StackOverflow? – donkopotamus

+0

Хотя я не потворствую названию, я вижу, откуда это взялось. Вы назвали что-то «полная глупость» без каких-либо дополнительных разъяснений. В Интернете полно таких ответов, и они бесполезны и раздражают большинство. @Bartek, я думаю, что ваше последнее предложение могло бы помочь в разъяснении этого момента, когда компилятор заполнил пропущенные вызовы уничтожения. Это делает все это более явным, более ясным. – Morpheu5

+1

@ Morpheu5 Я добавил стандартные ссылки для поведения по умолчанию-dtor. –

2

№ Это хорошо определено и ошибок компилятора, о которых я знаю.

7

Нет, вам не нужно это делать. Как часть нормального деструктора, каждый член класса будет уничтожен по очереди. Деструктор для умного указателя позаботится о необходимости учета, который в этом случае является неявным reset.

 Смежные вопросы

  • Нет связанных вопросов^_^