Inheritance 使用参数继承重写函数

Inheritance 使用参数继承重写函数,inheritance,function,c++-cli,overriding,Inheritance,Function,C++ Cli,Overriding,我有一个通用的items list类,可以使用它作为基类创建一个更具体的列表,如下所示 ref class ItemBase { } ref class ItemA : ItemBase { } ref class ItemList abstract { public: virtual void add(ItemBase ^p); } ref class ItemListA : ItemList { public: virtual void add(ItemA ^p) overrid

我有一个通用的items list类,可以使用它作为基类创建一个更具体的列表,如下所示

ref class ItemBase { }
ref class ItemA : ItemBase { }
ref class ItemList abstract {
 public:
  virtual void add(ItemBase ^p);
}
ref class ItemListA : ItemList {
 public:
  virtual void add(ItemA ^p) override; // it doesn't works :(
}

我想限制在每个类中添加特定类型的项。

这样做的公认模式是使基类方法受到保护:

ref class ItemBase { }
ref class ItemA : ItemBase { }
ref class ItemList abstract {
 protected:
  virtual void addInternal(ItemBase ^p);
}
ref class ItemListA : ItemList {
 public:
  virtual void add(ItemA ^p){addInternal(p);} 
}
这里有一个使用泛型的更好的解决方案。请注意,我们如何将泛型参数
T
约束为
itembease
,以强制此集合只能与
itembease
或其子类一起使用

ref class ItemBase { };
ref class ItemA : public ItemBase { };

generic <class T>
where T: ItemBase
ref class ItemList abstract {
 public:
     virtual void Add(T p){}
};

ref class ItemListA : ItemList<ItemA^> {
   //no need to override Add here
};

//usage
int main(array<System::String ^> ^args)
{
    ItemListA^ list = gcnew ItemListA();
    list->Add(gcnew ItemA());
}
ref类ItemBase{};
ref类ItemA:public ItemBase{};
通用的
其中T:ItemBase
ref类ItemList摘要{
公众:
虚空加法(tp){}
};
ref类ItemListA:ItemList{
//无需覆盖此处添加
};
//用法
int main(数组^args)
{
ItemListA^list=gcnew ItemListA();
列表->添加(gcnewitema());
}

不要将标记用于代码标记-只需将代码缩进4个空格,或者选择它并使用
010
按钮即可。还要注意C++和C++ +CLI是不同的语言。为此需要使用泛型或包容,而不是继承。无法使用继承,因为您违反了LSP。将不起作用,因为函数参数不是协变的。
addInternal
的约定是它接受任何
ItemBase
对象。派生类可以放松契约,但它们决不能拒绝接受对基类版本有效的参数。好吧,它将以您现在的方式工作,但是如果您要编写包装器函数,您应该使用包含而不是继承。请注意,另一个类仍然可以从
ItemListA
派生,直接调用
addInternal
,并打破不变量。我同意,这是一个相当不合理的示例,因为您通常会将基类设为泛型。然而,它确实解决了OP最初的问题,尽管有些尴尬。也许我有点急于宣布这是一个公认的apttern;)