У меня есть некоторые функции, которые могут группироваться, но не принадлежат некоторому объекту / объект и поэтому не могут рассматриваться как методы.
Так, в основном в этой ситуации я создал бы новое пространство имен и поместил бы определения в a header
файл, реализация в cpp
файл. Также (в случае необходимости) я создал бы анонимное пространство имен в этом cpp
файл и помещенный все дополнительные функции, которые не должны быть выставлены / включенный в интерфейс моего пространства имен там.
См. код ниже (вероятно, не лучший пример, и мог быть добит большего успеха с другой архитектурой программы, но я просто не могу думать о лучшем образце...),
Пример кода (header
)
namespace algorithm {
void HandleCollision(Object* object1, Object* object2);
}
Пример кода (cpp
)
#include "header"
// Anonymous namespace that wraps
// routines that are used inside 'algorithm' methods
// but don't have to be exposed
namespace {
void RefractObject(Object* object1) {
// Do something with that object
// (...)
}
}
namespace algorithm {
void HandleCollision(Object* object1, Object* object2) {
if (...) RefractObject(object1);
}
}
Пока все хорошо. Я предполагаю, что это - хороший способ управлять моим кодом, но я не знаю то, что должно я делать, если я имею некоторые основанные на шаблоне функции и хочу сделать в основном то же.
Если я использую шаблоны, я должен вставить весь свой код header
файл. Хорошо, но как я должен скрыть некоторые детали реализации затем?
Я хочу скрыться RefractObject
функция от моего интерфейса, но я не могу просто удалить его объявление (просто, потому что у меня есть весь свой код в a header
файл)...
Единственный подход, который я придумал, был чем-то как:
Пример кода (header
)
namespace algorithm {
// Is still exposed as a part of interface!
namespace impl {
template <typename T>
void RefractObject(T* object1) {
// Do something with that object
// (...)
}
}
template <typename T, typename Y>
void HandleCollision(T* object1, Y* object2) {
impl::RefractObject(object1);
// Another stuff
}
}
Какие-либо идеи, как сделать это лучше с точки зрения разработки кода?
Это довольно распространенное решение. Boost делает это, и я тоже, но вместо этого с пространством имен detail
. Просто возьмите за правило: «не заглядывайте внутрь деталь
!»
Что касается файла, я рекомендую предоставить детали в отдельный файл и спрятать его в папке деталей. То есть, мой код был бы похож на:
// v
#include "detail/RefractObject.hpp"
namespace algorithm {
template <typename T, typename Y>
void HandleCollision(T* object1, Y* object2) {
detail::RefractObject(object1);
// Another stuff
}
}
Это просто хорошая практика кода в целом (делайте вещи разделенными и повторно используемыми) и сохраняет файл заголовка более чистым от деталей реализации.
Вы не можете скрыть свой исходный код от пользователя, если вы не собираетесь сначала скомпилировать его, что невозможно с шаблонами. Поэтому я предлагаю, в некотором смысле, чтобы вы не беспокоились.
Также следует спросить, почему Refract не может быть членом метода.