Допустим, у нас есть класс Collection, такой как:
class CCollection {
public:
void add(B& b);
void remove(B& b);
void doSomethingWithAllObjects();
protected:
std::vector<B*> bs;
}
Где B — абстрактный класс и конкретное поведение
doSomethingWithAllObjects();
зависит от конкретного типа B, назовите его C.
Есть ли способ вывести CCollection и позволить методам
add(B b);
remove(B b);
просто принять производный тип?
Я думал о чем-то вроде переопределения таких методов:
class D : A{
public:
void add(C c);
void remove(C c);
void doSomethingWithAllObjects();
private:
std::vector<B*> bs;
}
или общая Java-конструкция, как
template<class T : B>
class C {
...//do lots of stuff
}
Выводы почти на 100% одинаковы. Но вы не должны смешивать различные производные Б.
Я уже читал, что почти невозможно ограничить классы шаблонов определенными типами, но должен быть способ избежать написания целого класса для каждого вывода B. Дело в том, что мне нужны функции, определенные в B, поэтому я не могу использовать простой шаблон
template<class T>
class B{
....
}
Конечно, я мог бы предположить, что другие программисты просто передают правильный тип правильной CCollection, но это не может быть духом. Я хочу заставить других программистов добавлять только один тип B.
Я не уверен, правильно ли я понял, но я думаю, что вы ищете простой шаблонная функция типа non-member. Функция шаблона может быть использована для проверки соответствия типов.
template<typename T>
void global_adder(const T& cl, const T& toadd) {
cl.add(toadd);
}
Так как не делает вычеты типа на основе наследования, это будет
убедитесь, что A не добавлен в B или B в C и так далее. Быть добавленным
оба аргумента должны иметь одинаковый тип. Ничего более.
Вы оставляете свой метод класса только в базовом классе. Сделай это
protected
и добавьте эту функцию как friend
,
Таким образом, вы будете теперь, что никто не может позвонить a.add
или же b.add
от
где-нибудь еще (не сможет добавить другой тип к определенному
учебный класс).
Единственный способ добавить или удалить элемент будет через шаблон
функции, которые обеспечивают соответствие типов.
Вы можете создать абстрактный базовый класс коллекции, например
class BaseCollection {
public:
void doSomethingWithAllObjects();
protected:
void addInternal(B* b); // consumes the element
std::vector<B*> bs; // or better use vector<shared_ptr> for reference count
};
template <typename C>
class Collection : public BaseCollection {
public:
void add(const C& c) {
C* my_copy = new C(c); // suppose we have a copy constructor
addInternal(my_copy);
}
};
Если вы попытаетесь создать экземпляр Collection<C>
где C
не подкласс B
, вы получите ошибку компиляции.