Возможно, вам будет лучше пропустить код и прочитать комментарии для краткого ознакомления с тем, что я пытаюсь сделать, однако есть более важные детали, которые я должен попытаться описать:Специализировать унаследованные шаблонные функции с текущим классом
Я хочу добавить функцию-член к классу, который унаследован через иерархию классов. Я хочу сделать так, чтобы производным классам не нужно было переписывать какой-либо код или делать что-либо особенное, чтобы автоматически получить эту функцию, и я бы хотел избежать макросов. Эта функция также должна быть унаследована любыми подклассами, сделанными после компиляции (это часть платформы, которую будут распространять другие люди).
Функция - это функция отладки, которая отслеживает настроенные интеллектуальные указатели (в отличие от std :: shared_ptr), которые указывают на экземпляры класса - я хочу узнать, почему данный экземпляр удерживается в памяти, что означает, что мне нужно знать, какие указатели указывают на него. Индивидуальные интеллектуальные указатели являются шаблонами, и я хочу обеспечить, чтобы специализация интеллектуального указателя, используемого в качестве аргумента, соответствовала типу статического типа экземпляра.
Поскольку это в рамках, разумно важно включить эту функцию для людей, расширяющих иерархию после компиляции.
Это компилируется в Windows с Visual Studio 2010. Мы скоро перейдем к VS 2015, но я бы предпочел не ждать. Мы также в основном перекрестной платформой (мы отключаем пару вещей для других платформ, только когда это необходимо). Если есть решение, для которого потребуется C++ 11/14/17/later, мне все равно хотелось бы услышать это из интереса.
Я чувствую, что мне нужно сделать функцию шаблонизированной и специализированной в одно и то же время, специализируясь на каком-то «Я», но я понятия не имею, как сделать подклассы получить то, что по существу скопировано, а не унаследовано код. Я также понимаю (я думаю), что эта функция не подходит для создания виртуальных, но я также хочу, чтобы подклассы не получали специализацию родительских классов.
Я думаю, что есть несколько вариантов, я могу пойти на, но я хотел бы знать, если есть что-то лучше, что я не подумал:
- Просто сдаваться на попытки достичь такого рода безопасности
- Вместо этого используйте динамическую проверку - я еще не разработал, как это сделать. Я думаю, что было бы легче, но менее безопасно, и мне нравится безопасность.
- Используйте макрос, чтобы автоматически сделать typdef к Себе, ала https://stackoverflow.com/a/21149648/78823
- Я не знаю точно, как это работает. В любом случае, это только половина проблемы, и я не думаю, что это приблизит меня к решению функции declare/inherit-but-not-really puzzle.
- Также не поклонник принуждения людей использовать макрос, особенно для чего-то, что только для отладки.
Я полностью ожидал, что совершенно другой шаблон дизайна будет лучшим решением, но такое решение не пришла мне в голову еще.
Я действительно думаю, что компилятор сможет узнать все, что мне нужно, чтобы поддержать это, но я не уверен, что язык это делает.
Я также очень благодарен за помощь или отзывы о том, как лучше сформулировать этот вопрос.Мне нелегко ловить голову вокруг проблемы, не говоря уже о том, чтобы ее понять другим людям.
template<class T>
class CustomSmartPointer {};
class Base {
public:
void doSomething(CustomSmartPointer<Base> arg) {} //Should be able to say something like CustomSmartPointer<Self> instead, where the compiler knows what I mean by Self
};
class Derived : public Base {
public:
void doSomething(CustomSmartPointer<Derived> arg) {} //Shouldn't have to specify this declaration, or code, again, as it is direcly copy-pastable from above
};
class Derived2 : public Base {};
void main() {
Base b;
Derived d;
Derived2 d2;
CustomSmartPointer<Base> cb;
CustomSmartPointer<Derived> cd;
b.doSomething(cb);
d.doSomething(cd);
d2.doSomething(cb); //This shouldn't compile, as cb is the wrong type for the specialisation that should exist for Derived2::doSomething
}
Кроме того, если кто-то говорит, что мы должны перейти к StD :: shared_ptrs, я думаю, я бы до сих пор точно такая же проблема. –
Обратите внимание, что 'void doSomething (CustomSmartPointer arg)' и 'void doSomething (CustomSmartPointer arg)' являются несвязанными функциями-членами (хотя они являются перегрузками с одним и тем же именем внутри 'Derived'). Если вы не хотите, чтобы 'void doSomething (CustomSmartPointer arg)' был доступен в 'Derived', тогда я не думаю, что наследование подходит в вашем случае. –
user2079303
Да, я это понимаю. Это что-то очень похоже на наследование, поэтому я не знаю, как это назвать. –