Объяснение C ++.
Подумайте о интерфейсе как об общедоступных методах классов.
Затем вы могли бы создать шаблон, который «зависит» от этих общедоступных методов, чтобы выполнить его (он выполняет вызовы функций, определенные в открытом интерфейсе классов). Предположим, что этот шаблон является контейнером, таким как векторный класс, и интерфейс, от которого он зависит, является алгоритмом поиска.
Любой класс алгоритмов, который определяет функции / интерфейс Vector, вызывает вызовы, которые удовлетворяют «контракту», (как объяснил кто-то в первоначальном ответе). Алгоритмы даже не должны быть одного базового класса; единственное требование состоит в том, что функции / методы, которые вектор зависит от (интерфейса), определены в вашем алгоритме.
Точка всего этого заключается в том, что вы могли бы предоставить любой другой алгоритм поиска / класс так же долго поскольку он предоставил интерфейс, от которого зависит вектор (поиск пузырьков, последовательный поиск, быстрый поиск).
Возможно, вам также захочется спроектировать другие контейнеры (списки, очереди), которые будут использовать тот же алгоритм поиска, что и Vector by если они выполняют интерфейс / контракт, на которые зависят ваши алгоритмы поиска.
Это экономит время (повторное использование кода ООП), так как вы можете написать алгоритм один раз, а не снова и снова, каждый новый объект, который вы создаете, без чрезмерного усложнения проблемы с заросшим деревом наследования.
Что касается «отсутствия» в отношении того, как все работает; (по крайней мере, на C ++), так как это работает в основном из стандартной среды библиотеки TEMPLATE.
Конечно, при использовании наследования и абстрактных классов изменяется методология программирования для интерфейса; но принцип тот же, ваши общедоступные функции / методы - это ваш интерфейс классов.
Это огромная тема и один из краеугольных принципов дизайна шаблонов.
Да, в OpenCV это безопасно.
Внутренне функция, подобная:
void somefunction(InputArray _src, OutputArray _dst);
, сделает что-то вроде:
Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
// dst filled with values
Итак, если src
и dst
:
create
фактически ничего не сделает, а модификации эффективно на месте . Некоторые функции могут clone
отображать src
внутри, если операция не может быть на месте (например, findConturs
в OpenCV> 3.2), чтобы гарантировать правильное поведение. create
создайте новую матрицу dst
без изменения src
. В документации указано, что это поведение по умолчанию не выполняется.
Примечательным примером является findContours
, которые изменяют матрицу src
. Вы справляетесь с этим, обычно проходя src.clone()
во входе, так что изменяется только клонированная матрица, но не та, которую вы клонировали.
Из OpenCV 3.2, findContours
не изменяет входное изображение .
Благодаря Фернандо Бертольди для рассмотрения ответа
EDIT: Теперь, когда вопрос был обновлен, я понимаю, что это не имеет никакого отношения. Однако я оставлю его здесь, если кто-то ищет подходящую проблему.
В целом с C ++, насколько безопасна эта ситуация, действительно зависит от тела рассматриваемой функции , Если вы читаете и записываете одну и ту же переменную напрямую, вы можете столкнуться с некоторыми серьезными логическими проблемами.
Однако, если вы используете временную переменную для хранения исходного значения перед ее перезаписью, это должно быть хорошо.
МАССИВНОЕ слово предупреждения, если вы работаете с массивами, Однако. Если вы пытаетесь сохранить все содержимое массива во временной переменной, вы должны быть осторожны, вы храните фактический массив, а не только указатель на него. Во многих ситуациях было бы целесообразно сохранять отдельные значения в массиве временно (например, в функции свопинга). Однако я не могу дать больше дальнейших рекомендаций в этом отношении, поскольку все зависит от того, что вы пытаетесь сделать.
Короче говоря, все зависит от реализации вашей функции.
src
иdst
в конечном итоге указывают на тот же блок памяти, поэтому ваш ответ неверен. Поскольку форма и тип совпадают, новая память не выделяется. См. Документацию дляcreate
. – Fernando Bertoldi 19 January 2017 в 18:07cv::threshold
, поскольку в источнике OpenCV есть примеры, которые используют тот же аргумент дляsrc
иdst
. – Fernando Bertoldi 19 January 2017 в 18:49