覆盖函数参数 /

Override function parameters /

本文关键字:参数 函数 覆盖      更新时间:2023-10-16

假设我们有一个集合类,如下所示:

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;      
}  

或通用的爪哇结构,如

template<class T : B>
class C {
    ...//do lots of stuff
}

推导几乎 100% 相同。但你不能混合B的不同派生。

我已经读过将模板类限制为某些类型几乎是不可能的,但必须有一种方法可以避免为 B 的每个派生编写整个类。关键是,我需要 B 中定义的函数,所以我不能使用简单的模板

template<class T>
class B{
  ....
} 

当然,我可以假设其他程序员只是将正确的类型交给正确的CCollection,但这不可能是精神。我想要的是强迫其他程序员只添加一种类型的B。

我不确定我是否正确理解,但我认为您正在寻找一个简单的模板非成员类型函数。模板函数可用于确保类型匹配。

template<typename T>
void global_adder(const T& cl, const T& toadd) {
    cl.add(toadd);
}
  • 由于不进行基于继承的类型推断,这将确保 A 未添加到 B 或 B 添加到 C 等。待添加两个参数必须具有相同的类型。而已。

  • 仅将类方法保留在基类中。来得及 protected并将此功能添加为friend

  • 这样,您现在就可以从中拨打a.addb.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 的子类,则会收到编译错误。