Переопределить параметры функции /

Допустим, у нас есть класс 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.

0

Решение

Я не уверен, правильно ли я понял, но я думаю, что вы ищете простой шаблонная функция типа 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 от
    где-нибудь еще (не сможет добавить другой тип к определенному
    учебный класс
    ).

  • Единственный способ добавить или удалить элемент будет через шаблон
    функции, которые обеспечивают соответствие типов.

0

Другие решения

Вы можете создать абстрактный базовый класс коллекции, например

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, вы получите ошибку компиляции.

-1

По вопросам рекламы [email protected]