Похож на Вас, пытаются защитить от медленная распределенная грубая сила . Не то, чтобы очень можно делать с этим. Мы используем PKI и никакие логины пароля. Помогает, но если Ваши клиентские рабочие станции шанса время от времени, это не очень применимо.
Потому что это не приведет к глубокому клонированию, а это обычно то, чем действительно должны быть клоны. Представьте, что у вас есть ссылка на массив или список ... простое копирование памяти, занятой вашим объектом , просто клонирует ссылку. Любые изменения в массиве будут видны как через клон, так и через исходный объект, поэтому два объекта по-прежнему связаны, что нарушает обычную точку клонирования.
Если вы хотите реализовать именно эту функциональность, это просто - это для чего предназначен Object.MemberwiseClone ()
. Большую часть времени,
Другие уже рассказали о MemberwiseClone
, но никто не объяснил , почему он защищен. Я попытаюсь дать объяснение.
Проблема в том, что MemberwiseClone
просто слепо копирует состояние. Во многих случаях это нежелательно. Например, объект может иметь частное поле, которое является ссылкой на список List
. Неглубокая копия, такая как то, что делает MemberwiseClone
, приведет к появлению нового объекта, указывающего на тот же список - и класс вполне может быть написан, не ожидая, что список будет передан кому-либо еще.
Или объект может иметь какое-то поле идентификатора, сгенерированное в конструкторе - опять же, когда вы его клонируете, вы получаете два объекта с одинаковым идентификатором, что может привести ко всевозможным странным сбоям в методах, предполагающих, что идентификатор уникален.
Или скажем, у вас есть объект, который открывает сокет или файловый поток и сохраняет ссылку на него. MemberwiseClone
просто скопирует ссылку - и вы можете представить, что два объекта, пытающиеся перемежать вызовы одного и того же потока, не закончатся хорошо.
Короче говоря, «клонирование» - это не лучший вариант. определенная операция для произвольных объектов. Тот факт, что элементарный operator =
предоставляется для всех классов по умолчанию в C ++, является большим неудобством, так как слишком часто люди забывают, что он есть, и не отключают его для классов, для которых копирование не имеют смысл или опасны (а таких классов на удивление много).
Или, скажем, у вас есть объект, который открывает сокет или файловый поток и хранит ссылку на него. MemberwiseClone
просто скопирует ссылку - и вы можете представить, что два объекта, пытающиеся перемежать вызовы одного и того же потока, не закончатся хорошо.
Короче говоря, «клонирование» - это не лучший вариант. определенная операция для произвольных объектов. Тот факт, что элементарный operator =
предоставляется для всех классов по умолчанию в C ++, является большим неудобством, так как слишком часто люди забывают, что он есть, и не отключают его для классов, для которых копирование не имеют смысл или опасны (а таких классов на удивление много).
Или, скажем, у вас есть объект, который открывает сокет или файловый поток и хранит ссылку на него. MemberwiseClone
просто скопирует ссылку - и вы можете представить, что два объекта, пытающиеся перемежать вызовы одного и того же потока, не закончатся хорошо.
Короче говоря, «клонирование» - это не лучший вариант. определенная операция для произвольных объектов. Тот факт, что элементарный operator =
предоставляется для всех классов по умолчанию в C ++, является большим неудобством, так как слишком часто люди забывают, что он есть, и не отключают его для классов, для которых копирование не имеют смысл или опасны (а таких классов на удивление много).
MemberwiseClone
просто скопирует ссылку - и вы можете представить, что два объекта, пытающиеся перемежать вызовы одного и того же потока, не закончатся хорошо.
Короче говоря, «клонирование» - это не лучший вариант. определенная операция для произвольных объектов. Тот факт, что элементарный operator =
предоставляется для всех классов по умолчанию в C ++, является большим неудобством, так как слишком часто люди забывают, что он есть, и не отключают его для классов, для которых копирование не имеют смысл или опасны (а таких классов на удивление много).
MemberwiseClone
просто скопирует ссылку - и вы можете представить, что два объекта, пытающиеся перемежать вызовы одного и того же потока, не закончатся хорошо.
Короче говоря, «клонирование» - это не лучший вариант. определенная операция для произвольных объектов. Тот факт, что элементарный operator =
предоставляется для всех классов по умолчанию в C ++, является большим неудобством, так как слишком часто люди забывают, что он есть, и не отключают его для классов, для которых копирование не имеют смысл или опасны (а таких классов на удивление много).
Существует (по крайней мере) два вида клонирования. В большинстве источников говорится о мелком и глубоком клонировании, но на самом деле между ними есть оттенки.
Ключевая проблема - это противоречие между тем, «сколько следует скопировать» и «сколько» должны быть общими ".
Рассмотрим объект Order
, содержащий ссылки на клиента
, адрес
и список List
из OrderLines
.
Если вы хотите Clone ()
an Order
, в чем дело?
" Просто копирование блока памяти "даст вам новый Заказ
, но тот, который разделяет Клиента
, Адрес
и тот же Список
из OrderLines
. (Помните, что члены объекта хранятся по ссылке, поэтому, когда вы дублируете блок памяти, вы получаете две ссылки на один и тот же объект.)
Очевидно, вы не хотите делиться списком
of OrderLines
между двумя Order
s. Фактически, вы, вероятно, захотите также клонировать каждую OrderLine
.
Если бы вы работали с методом общего назначения Clone ()
, как бы этот метод узнал, какие члены должны быть рекурсивно клонированы, а какие нет?
В общем, это неразрешимая проблема - вот почему отдельные объекты должны реализовать подходящую семантику для своей ситуации .
И последнее замечание: даже когда я создаю возможность Clone ()
объектов, я не склонен создавать метод Clone ()
, вместо этого предпочитаю конструктор копирования - конструктор, принимающий за основу другой объект. Если вы не можете найти Clone ()
, поищите его.
Вы должны явно реализовать интерфейс ICloneable в своих классах.
Однако, как указано в документации, механизм клонирования в MemberwiseClone делает не различать мелкую и глубокую копию.
Существует такая вещь, как Object.MemberwiseClone (), , которая выполняет то, что вы описываете. Он делает неглубокую копию объекта.
Он не будет выполнять глубокое клонирование автоматически ... вам нужно будет вызвать clone для всех объектов-членов вручную и т. Д.