C++ C+中具有继承性的对象向量+; 类IFeature { 公众: 虚拟std::string string()=0; }; 类特征2D { 公众: 虚拟std::string string(){..} }; 类特征3D { 公众: 虚拟std::string string(){..} }; 无效打印(标准::矢量和v) { 对于(尺寸i=0;i

C++ C+中具有继承性的对象向量+; 类IFeature { 公众: 虚拟std::string string()=0; }; 类特征2D { 公众: 虚拟std::string string(){..} }; 类特征3D { 公众: 虚拟std::string string(){..} }; 无效打印(标准::矢量和v) { 对于(尺寸i=0;i,c++,inheritance,vector,C++,Inheritance,Vector,使用模板 class IFeature { public: virtual std::string string() = 0; }; class Feature2D { public: virtual std::string string() { .... } }; class Feature3D { public: virtual std::string string() { .... } }; void print(std::vector<IFeature*>

使用模板

class IFeature
{
public:
  virtual std::string string() = 0;
};

class Feature2D
{
public:
  virtual std::string string() { .... }
};

class Feature3D
{
public:
  virtual std::string string() { .... }
};

void print(std::vector<IFeature*> & v)
{
  for (size_t i=0; i<v.size(); i++)
    std::cout << v[i]->string() << std::endl;
}

void main()
{
  std::vector<Feature2D*> v2d;
  // push...
  print(v2d); // compile error 

  std::vector<Feature3D*> v3d;
  // push...
  print(v3d); // compile error 
}
模板无效打印(std::vector const&v){

对于(size_t i=0;i只需将向量设为IFeature*-vectors。您可以在其中存储继承类的指针

inline std::ostream & operator<<(std::ostream & Dest, IFeature const & v) {
  v.print(Dest);
  return Dest;

void print(std::vector<IFeature *> const & v) {
  for (size_t i=0; i<v.size(); i++)
    std::cout << *(v[i]) << std::endl;
}
std::vector v2d;
v2d.推回(新特性2d());
打印(v2d);
无需使用模板。当您需要访问公共虚拟函数时,指向超类的指针是一种方法。通过这种方法,您还可以在同一个向量中混合不同的子类:

std::vector<IFeature*> v2d;
v2d.push_back(new Feature2D());
print(v2d);
std::vector vMixed;
vMixed.push_back(新特性2d());
vMixed.push_back(新特性3d());
打印(vMixed);

当然,如果您还需要继承类的指针,事情会变得有点棘手。一个选项是将它们单独存储在其他位置。您也可以进行向下转换,但通常不建议这样做。

您可以将
自身打印到模板中:

std::vector<IFeature*> vMixed;
vMixed.push_back(new Feature2D());
vMixed.push_back(new Feature3D());
print(vMixed);
模板
无效打印(T常量和v)
{

对于(sisixt t=0;i<p),这里所寻找的是接口协方差,在C++类中,(这是我所知的)是不可能的。您需要使打印也成为模板化函数(用t*替换iFix**)。

为了完整性,我将补充说明,因为所有向量共享相同的二进制代码,所以可以重新解释向量。

template<typename Iter>
void print(Iter begin, Iter end) {
  for (Iter i = begin; i != end; ++i)
    std::cout << (*i)->string() << std::endl;
}
打印(重新解释铸造(v2d));
C++没有模板参数的协方差,但如果你知道它在引擎盖下的作用,你可以部分地模拟它。我发现重新解释cast对于将
向量&
转换为
向量&
进行逆变换也很有用


当然,这很难看。

非常感谢!那个“const”是干什么的?它表示打印不会修改v。但是,如果您需要通过向量访问继承的类,这将不起作用。(您需要难看的下拉列表。)您可以(而且应该)通过常量引用将向量传递到
print
。此外,您的
FeatureXD
类声明中缺少继承语句。@Stefan-请不要建议对问题中发布的代码进行编辑。任何错误都可能是OP看到的问题的原因。是的,当然,我当时在想什么:)我会更进一步,建议您在迭代器上操作,而不是在对T的常量引用上操作。因此:模板void print(inputierator begin,inputierator end){…}
std::vector<IFeature*> vMixed;
vMixed.push_back(new Feature2D());
vMixed.push_back(new Feature3D());
print(vMixed);
template<typename T>
void print(T const &v)
{
  for (size_t i=0; i<v.size(); i++)
    std::cout << v[i]->string() << std::endl;
}
template<typename T>
void print(T const &v)
{
  for (T::const_iterator i = v.begin(); i != v.end(); ++i)
    std::cout << (*i)->string() << std::endl;
}
template<typename Iter>
void print(Iter begin, Iter end) {
  for (Iter i = begin; i != end; ++i)
    std::cout << (*i)->string() << std::endl;
}
print(reinterpret_cast<std::vector<IFeature*>&>(v2d));