Я пытаюсь выполнить следующее:Производный класс без накладных расходов с использованием шаблонов?
- Объект.
- Отладка версии объекта с дополнительной функциональностью в функции для отслеживания.
Теперь у меня есть решение для компиляции с использованием макросов, которые разрешают do {} while(0)
, если библиотека не скомпилирована с соответствующим флагом.
Я бы хотел, чтобы эта функциональность была включена во время выполнения. Каков наилучший способ сделать это?
Я бы хотел: Base * obj = (isGlobalDebugEnabled) ? new Debug(...) : new Base(...);
тип предмет. Неужели я не хочу чего-то подобного?
Примечание. Стандартная виртуальная функция на самом деле не решает проблему, так как каждая функция должна дублироваться в производной (отладочной) версии объекта, превзойдя цель.
Кроме того, функции нижнего уровня чрезвычайно велики (более 600 миллиардов вызовов при профилировании), поэтому я хочу иметь скомпилированное нулевое служебное решение для «базового класса». Разумеется, объект Debug может быть медленнее.
Вот почему я подумал о шаблонах. ПРИМЕЧАНИЕ. У меня нет доступа к C++ 11/boost помимо функций VS2010 (базовые lambdas и т. Д.). Могу ли я сделать что-то вроде
template <bool debug = false>
class Object {
std::enable_if<debug> void printTrace(); // Add functions based on debug/not
};
void Object::doSomething(...){
<only do this if debug without runtime check> addToTrace(...);
doTheStuff();
}
Я видел this link который указал мне в направлении поддельного наследования с помощью шаблонов, если это помогает.
Спасибо за вашу помощь
AK
EDIT: Я просто понял, что может идти об этом неправильном пути - может быть, есть объект Debug в качестве базового класса, и переопределить функциональность no-ops в объекте Regular. Кажется, это лучший способ. Тем не менее, я все равно хотел бы избежать прыжка vtable из-за этих высокопроизводительных требований, поэтому, я думаю, мои вопросы по шаблону все еще стоят? может быть?
EDIT2: Как KerrickSB указывалось, примером использования может быть более ясным:
основной код EXE:
void ComputeSomething() {
Object * obj = (globalDebugFlag) ? new DebugObject(...) : new Object(...);
obj->insertElement(elem); // Inserts in Object, Inserts and traces actions in DebugObject
...
}
, где объект находится в отдельной DLL, и где globalDebugFlag
является (предлагаемая) глобальная переменная, заданная командой, поступающей через отдельный порт, чем та, которая вызывала вызов ComputeSomething().
Я планировал использовать глобальные переменные трассировки, которые затем возвращают трассировку через порт (через глобальный объект, который обрабатывает этот порт) для отображения на переднем конце инструмента.
Являются ли функции отладки всегда одинаковыми, то есть есть общий «интерфейс отладки»? –
Если функциональность отладки не переплетена, вы можете просто создать функции отладки в производном классе Debug следующим образом: 'virtual void foo() {/ * debug stuff */Base :: foo(); } ' В противном случае, я думаю, вы могли бы просто разделить функциональность на несколько функций (возможно, встроенный? Не уверен, можете ли вы это сделать) и использовать этот подход в каждом месте. – Svalorzen
Не могли бы вы привести простой пример того, как вы хотели бы * использовать * свое решение (возможно, в псевдокоде)? –