2014-04-02 1 views
3

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

Применить [алгоритм [K]] для данных в [I] и сохранить в [о]

Сузить до моих сомнений:

a) Возможно, что вход и выход являются одним и тем же объектом, например, при применении фильтра Гаусса к изображению.

b) Возможно, алгоритм разрешен без операции, например, при интерполяции массива данных на другой размер того же размера.

Когда (а) и (б) происходит в то же время, в следующую часть алгоритма

o[output_position]=process(i[input_position]); 

Будет решительный к

o[output_position]=o[output_position]; 

Является ли это безопасно?


Некоторые довольно-не-полированная рассуждения:

Я предполагаю, что это, в основном потому, что (но я не чувствую себя уверенно с этим предположением) память-память перемещается решает памяти-to перемещение по регистру.

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

Я планирую скомпилировать флаги оптимизации и перейти к другим частям проекта, поэтому я волнуюсь, что где-то в будущем идут BOOM, и там идет еще один приятный день, проведенный на отладчике, для отслеживания этого самоназначения.

Заранее благодарен.

ответ

3

Это полностью зависит от типа o[output_position]. Если он правильно выполняет оператор присваивания, то это нормально. Правильно реализованный оператор присваивания всегда отлично работает с самоназначением.

Идиоматическая реализация оператора присваивания в C++ использует copy-and-swap idiom. Это подразумевает правильное самоопределение, даже без проверки this != &other, которое вы часто увидите в других реализациях.

+0

+1 для упоминания идиомы копирования и замены. – Veritas

1

При использовании базовых типов (int, float, char) ваши рассуждения будут точными - любое назначение выполняется с помощью памяти-памяти, которая достаточно быстро.

При использовании объектов вам необходимо правильно реализовать оператор присваивания (operator =). Это, скорее всего, будет сделано путем проверки, как вы должны, что вы не назначая объект к себе:

Object operator=(const Object& other) { 
    if (&other == this) { return *this }; 

    // your assignment code here! 
} 
+0

Неправда или, по крайней мере, не полный ответ. Прежде всего, если ваш класс использует только переменные-члены, которые имеют правильную семантику назначения, то это избыточно (и даже подвержено ошибкам) ​​для реализации вашего собственного оператора присваивания. Во-вторых, если вы используете copy-and-swap, вам не нужна проверка самонаведения, за исключением, возможно, некоторых экзотических случаев оптимизации. –

+0

Танки, @Arie, я забыл упомянуть, что я действительно беспокоюсь об основных типах, потому что тогда назначение происходит локально (под этим я подразумеваю, что оператор копирования не называется) – Kahler

+0

@Kahler: копия и назначение связаны, но не то же самое:) В любом случае, назначение базовых типов всегда прекрасное. Вы можете столкнуться с проблемами с указателями, но это зависит от желаемой семантики собственности (присваивания адреса и назначения того, на что указывает). Итак, все рассмотренное, я думаю, ваш вопрос хорош и хорошо выражен, но, возможно, должен был упомянуть еще несколько деталей реализации. –

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