假设我们有一个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;
}
或像
这样的通用javaish构造template<class T : B>
class C {
...//do lots of stuff
}
推导几乎100%相同。但是你不能混合B的不同派生。
我已经读过它几乎不可能将模板类限制为某些类型但是必须有一种方法可以避免为每个B的派生编写一个完整的类。重点是,我需要在B中定义的函数,所以我可以不要使用简单的模板
template<class T>
class B{
....
}
当然我可以假设其他程序员只是将正确的类型交给正确的CCollection,但这不是精神。我想要的是强迫其他程序员只添加一种类型的B。
答案 0 :(得分:0)
我不确定我是否理解正确,但我认为您正在寻找一个简单的 模板非成员类型函数 。模板函数可用于确保类型匹配。
template<typename T>
void global_adder(const T& cl, const T& toadd) {
cl.add(toadd);
}
由于不会根据遗产进行类型扣除,因此会这样做 确保A未添加到B或B添加到C等等。待补充 两个args必须具有相同的类型。没有更多。
您只能将类方法保留在基类中。做了
protected
并将此功能添加为friend
。
这样你现在就没有人可以拨打a.add
或b.add
了
在其他地方(将无法添加不同的类型
类)。
添加或删除元素的唯一方法是通过模板 确保类型匹配的函数。
答案 1 :(得分:-1)
您可以创建一个抽象的基本集合类,如
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
的子类,则会出现编译错误。