О: template
class destructivecopy_pointer
2 : {
private:
T* pObject;
Типы интеллектуальных указателей
|
581
|
public:
destructivecopy_pointer(Т* plnput):pObject(plnput) {}
~destructivecopy_pointer() { delete pObject; }
8
9 // конструктор копий
destructivecopy_pointer(destructivecopy_pointer& source)
{
// Взять копию в собственность
pObject = source.pObject;
14
// удалить первоисточник
source.pObject = 0;
}
18
// Оператор присвоения копии
destructivecopy_pointer& operator= (destructivecopy_pointer& rhs)
{
if (pObject != source.pObject)
{
delete pObject;
pObject = source.pObject;
source.pObject = 0;
27
28
29
30
int main()
{
destructivecopy_pointer pNumber (new int);
destructivecopy_pointer pCopy = pNumber;
// pNumber теперь недопустим
return 0;
}
Анализ
листинге 26.3 показана самая важная часть реализации интеллектуального указа теля деструктивного копирования. Строки 10-17 и 20-28 содержат конструктор копий и оператор присвоения копии соответственно. Эти функции делают первоисточник недей ствительным при его копировании; т.е. после копирования конструктор копий устанавли вает указатель, содержавшийся первоисточником, в NULL, оправдывая название деструк тивное копирование. Оператор присвоения делает то же самое. Таким образом, указатель pNumber фактически объявляется недопустимым в строке 34, когда присваивается друго му указателю. Это поведение противоестественно действию присвоения.
ВНИМАНИЕ!
Конструктор копий и оператор присвоения копии, которые критически важны для реализации интеллектуальных указателей деструктивного копирования, также продемонстрированные в листинге 26.3, вызывают максимум критики. В отличие от большинства классов C++, у этого не может быть конструктора ко пий и оператора присвоения получающих константные ссылки, поскольку они
582 ЗАНЯТИЕ 26. Понятие интеллектуальных указателей
должны объявлять первоисточник недопустимым после его копирования. Это не только отклонение от традиционной семантики конструктора копий и оператора присвоения, это делает использование класса интеллектуального указателя не интуитивно понятным. Немногие ожидают, что оригинал копии или первоисточ ник присвоения окажутся недопустимы после присвоения или копирования. Тот факт, что такие интеллектуальные указатели уничтожают первоисточник, также делает их неподходящими для использования в таких контейнерах библиоте ки STL, как s t d : : v e c to r, или любой другой динамический класс коллекции, который вы могли бы использовать. Эти контейнеры должны копировать свое содержимое внутренне, а все заканчивается тем, что указатели оказываются недопустимыми.
По совокупности этих причин многие разработчики боятся интеллектуальных указателей деструктивного копирования как чумы.
СОВЕТ
|
До сих пор
|
по стандарту
|
C++ основным интеллектуальным указателем де
|
|
структивного
|
копирования
|
считался указатель au to _ p tr. Теперь, в C++11,
|
|
его применение не рекомендуется, и вместо него следует использовать класс
|
|
s td : :u n iq u e _ p tr.
|
|
Do'stlaringiz bilan baham: |