2011-02-17 113 views
2
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)在C++中继承对象的向量

谢谢

+1

你可以(也应该)通过const引用将你的向量传递给`print`。此外,您的`FeatureXD`类声明中缺少继承声明。 – 2011-02-17 12:02:31

+0

@Stefan - 请不要对发布在代码中的代码提出修改建议。可能是因为任何错误都是OP看到问题的原因**。 – ChrisF 2011-02-17 12:47:55

+0

是的,当然,我在想什么:) – 2011-02-17 14:11:45

回答

2

使用模板。

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

或者,使用虚拟打印成员函数:

class IFeature 
{ 
public: 
    virtual std::string string() = 0; 
    virtual void print(std::ostream & Dest) const = 0; 
}; 

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

可选择与运营商< <

+0

非常感谢! “const”的用途是什么? – yelo3 2011-02-17 11:58:09

2

结合就使向量的iFeature * - 载体。你可以将继承类的指针存储在它们中。

std::vector<IFeature*> v2d; 
v2d.push_back(new Feature2D()); 
print(v2d); 

无需使用模板。当您需要访问通用虚拟功能时,指向超类的指针就是要走的路。这样,您还可以在同一载体中混合使用不同的子类:

std::vector<IFeature*> vMixed; 
vMixed.push_back(new Feature2D()); 
vMixed.push_back(new Feature3D()); 
print(vMixed); 

当然,如果你还需要继承类的指针,事情变得有点更靠谱。一种选择是将它们分别存储在别处。你也可以低调,但通常不推荐。

1

您可以print自己变成一个模板:

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

你在找什么因为这里是接口协方差,它(就我所知)在C++类中是不可能的。您还需要打印模板功能(用T *替换IFeature *)。

1

为了完整起见,我会补充说您可以reinterpret_cast载体,因为所有载体都共享相同的二进制代码。

print(reinterpret_cast<std::vector<IFeature*>&>(v2d)); 

C++没有为模板参数协方差,但你可以模拟它部分,如果你知道它的引擎盖下。我发现reinterpret_cast也可用于将vector<T*>&转换为vector<const T*>&作为反转。

当然,这是非常丑陋的。