Я обычно не реализую ни одного, пока мне не нужен тот. Я одобряю интерфейсы по абстрактным классам, потому что это дает немного больше гибкости. Если существует общее поведение в некоторых наследующих классах, я перемещаю это вверх и делаю абстрактный базовый класс. Я не вижу потребность в обоих, так как они по существу сервер, той же целью, и имеющий обоих является плохой запах кода (по моему скромному мнению), что решение было сверхспроектировано.
Чтобы подробно остановиться на ответе @bgooddr, вот, функция CMake для получения местоположения цели:
function(get_fancy_lib_location)
set(options)
set(multiValueArgs LIB)
set(oneValueArgs LOCATION)
cmake_parse_arguments(get_fancy_lib_location "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
message (STATUS "fancy_lib == ${get_fancy_lib_location_LIB}")
get_property(fancy_lib_location TARGET "${get_fancy_lib_location_LIB}" PROPERTY LOCATION)
message (STATUS "fancy_lib_location == ${fancy_lib_location}")
set(${get_fancy_lib_location_LOCATION} ${fancy_lib_location})
endfunction()