#c #oop #templates #polymorphism #virtual
Вопрос:
я пытаюсь решить эту проблему в течение некоторого времени и надеюсь найти здесь некоторую помощь. У меня есть базовый класс, и внутри базового класса мне нужен метод шаблона. Но этот метод не может быть виртуальным (что я знаю), поэтому я не могу переопределить его в дочернем классе, но есть ли какая-либо альтернатива или обходной путь? Какой-то шаблон дизайна? Спасибо
#include <iostream>
#include <vector>
#include <map>
class ABase {
public:
ABase() :
id(s_id )
{}
size_t static s_id;
size_t id;
};
size_t ABase::s_id(0);
class A1 : public ABase {
public:
};
class A2 : public ABase {
public:
};
class BBase {
public:
};
class B1 : public BBase {
public:
};
class B2 : public BBase {
public:
};
class ComboBase {
public:
// this cannot be virtual :(
// so i cannot store b in bs in the child class
/* virtual */ template<typename T>
void addB(T b) {
}
};
template<class T, class T2>
class Combo : public ComboBase {
public:
// override of template method is not possible
/*
template<typename T>
void addB(T b) override {
bs.push_back(b);
}
*/
size_t id;
std::shared_ptr<T> a;
std::vector<std::shared_ptr<T2>> bs;
};
int main() {
std::map<size_t, std::shared_ptr<ComboBase>> combos;
auto combo1 = std::make_shared<Combo<A1, B1>>();
auto combo2 = std::make_shared<Combo<A2, B2>>();
combos[combo1->id] = combo1;
combos[combo2->id] = combo2;
// here is the problem... later i the code
// i would like to add Bs to the existing combo but i cannot use
// virtual templates
auto b1 = std::make_shared<B1>();
auto b2 = std::make_shared<B2>();
auto it1 = combos.find(0);
if (it1 != combos.end()) {
it1->second->addB(b1);
it1->second->addB(b2);
}
auto it2 = combos.find(0);
if (it2 != combos.end()) {
it2->second->addB(b1);
it2->second->addB(b2);
}
}
Комментарии:
1. @KonradRudolph ой, мой плохой — не прокрутил достаточно далеко вниз.
2.
template<typename T> void addB(T b)
Шаблон функции, подобный этому, должен быть способен принимать любые аргументы. Что должно произойти, если я позвонюaddB(42)
илиaddB(new int[1000])
илиaddB(std::string("good bye, cruel world"))
?3. Обычно я бы сказал CRTP , но то, как вы его используете, кажется, не вариант.