【问题标题】:How to implement function with vector of derived classes as parameter如何以派生类的向量为参数实现函数
【发布时间】:2011-05-16 00:17:26
【问题描述】:

(与我之前问过的unanswered question有关)。我想实现一个函数,该函数只能以相关类的向量作为参数调用。

对于情商

如果我们有

class A;
class B: public A;
class C: public A;
class D

then it should be possible to call function with vector<A*>,vector<B*> or 
vector <C*> but not vector <D*>

任何建议

【问题讨论】:

    标签: templates vector implementation idioms


    【解决方案1】:

    我猜你已经尝试过创建类似的方法

    void doSomething(std::vector<A*>& things)
    {
    }
    

    并尝试过通过

    std::vector<B*> bList = ...;
    doSomething(bList);
    

    对吗?

    为什么编译器会抱怨?因为这没有意义。考虑 doSomething() 尝试做的事情

    things.push_back(new C());
    

    这不能工作,因为“事物”实际上是 std::vector&lt;B*&gt;。但是,如果是std::vector&lt;A*&gt;,push_back 就可以了。

    那么我们可以从中学到什么?仅当您仅从向量中读取时,您正在尝试的内容才有意义,但是,向量不是只读容器。

    一个简单的包装器展示了一个可能的解决方案(当然,包装器可以根据您的需要进行调整)。但是,我必须指出,使用虚拟方法可能会导致性能下降。

    class A {};
    class B : public A {};
    
    template <class Base>
    class AbstractVectorWrapper
    {
    public:
        virtual size_t size() const = 0;
        virtual Base* getElementAt(int index) const = 0;
    };
    template <class Base, class Derived>
    class VectorWrapper : public AbstractVectorWrapper<Base>
    {
    private:
        std::vector<Derived*> m_vector;
    public:
        explicit VectorWrapper(std::vector<Derived*> const& vector)
            : m_vector(vector)
        {
        }
        virtual size_t size() const
        {
            return m_vector.size();
        }
        virtual Base* getElementAt(int index) const
        {
            return m_vector[index];
        }
    };
    
    void doSomething(AbstractVectorWrapper<A> const& wrapper)
    {
        for (size_t i=0;i<wrapper.size();i++)
        {
            A* a = wrapper.getElementAt(i);
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        std::vector<A*> as;
        std::vector<B*> bs;
        doSomething(VectorWrapper<A,B>(bs));
        doSomething(VectorWrapper<A,A>(as));
    
    
        return 0;
    }
    

    【讨论】:

    • 我知道这是不可能的,因此问题:-)
    • 我说为什么它不能工作,而不是它不能,因此我的回答:-)。
    【解决方案2】:

    duck-typing 是否适合您?考虑这段代码

    template <class T>
    void my_function (std::vector <T*> const &values) {
        // Use features of A* here
    }
    

    如果您使用指向 T 的指针不支持的功能,这将无法编译。通过使用A 的功能,我认为应该保证指向BC 的指针也可以按预期工作。但是,如果D 的接口符合my_function 的要求,则可以使用D * 的向量调用此函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      • 2019-07-16
      • 1970-01-01
      相关资源
      最近更新 更多