2012-10-20 24 views
1

作爲模板編程的新手,我正在試圖構建一個結構迷路。在模板類中,如何處理未指定的基類對象數組?

class Base; 

template <typename T> 
class Foo : public Base { 
protected: 
    T mValue; 
    std::vector<Base> mFooVector; // the idea is to have Foo<T> elements 
            // of several T types 

public: 
    T value() { 
     return mValue; 
    } 

    void SetValueFromVector() { 
     mValue = Transform(mFooVector); 
     // to give you an idea of what awaits below 
    } 

    T Transform(std::vector<Base>) { 
     // Question deals with what I want to do here 
    } 

    /*...*/ 
} 

class Base{ 
    // here, how to declare a virtual or template 'value()' 
    // that could be instantiated or specialized within Foo? 
    // Or should I declare a public 'mValue' of some type? 
    // (see below) 
}; 

Transform我想從它可以佈置成各種類型關聯「mFooVector」的所有元素調用值()。將會有其他地方定義的功能處理所有可能的實際案例。 但是,如何從Base類的實例聲明的對象中調用value()或訪問mValue,仍然存在問題。

昨天我問了一個question這只是我的研究的開始 - 問題不再是容器了,因爲我使用了多態性,但事實上我需要調用其包含的實例的value()函數。

編輯:萬一它幫助任何人,這裏是我最終定義的類的方式。我接受了@PiotrNycz的回答,因爲它讓我真的接近了我的目標,但它並沒有完全實現我所需要的。

class Base { 
public: 
    virtual void setValue(&int) =0; 
    virtual void setValue(&float) =0; 
    virtual void setValue(&double) =0; 
} 

template <typename T> 
class Foo : public Base { 
protected: 
    T mValue; 
    std::vector<Base*> mFooVector; 
    T Transform(std::vector<Base*>); 
public: 

    // this is for use from outside the class 
    T value() { 
     return mValue; 
    } 

    void SetValueFromVector() { 
     mValue = Transform(mFooVector); 
    } 

    // the three below are only going to be used within 'Transform' 
    void setValue(int& i) { i = mValue; } 
    void setValue(float& f) { f = (float) mValue; } 
    void setValue(double& d) { d = (double) mValue; } 
} 

// specialization of Transform 
template<> 
int Foo<int>::Transform(std::vector<Base*> v) 
{ 
    // here I only use setValue functions 
    // if for example I know that first v element is 'float' 
    float val; 
    v[0]->setValue(val); 

    return 3*int(val); 
} 
// and etc. 
+1

如果你想要_polymorphism_,你將需要'std :: vector ',否則你會在_slicing_中產生。 –

+0

好的,謝謝你的評論。我認爲我的問題仍然存在,但如果向量的元素是指針,我仍然想在它們上應用value()。 – nenj

+0

[如何將不同的模板類型放到一個向量中]可能的重複(http://stackoverflow.com/questions/696399/how-to-put-different-template-types-into-one-vector) – jogojapan

回答

0

我假設你知道所有可能的值類型,讓我們說他們是int/float/...,那麼你的基類必須(由純虛方法)準備做添加任何值類型:

class Base { 
public: 
    virtual ~Base() {} 
    virtual void addTo(int& value) = 0; 
    virtual void addTo(long& value) = 0; 
    virtual void addTo(float& value) = 0; 
    virtual void addTo(double& value) = 0; 
    // add as many functions as you need and of types you need in your design 
    // these types not necessarily must be simple basic types 
}; 

template <class Type> 
class Foo : public Base { 
public: 
    T Transform(std::vector<Base>) { 
     T retVal = T(); 
     // Question deals with what I want to do here 
     for (auto it = mFooVector.begin(); it != mFooVector.end(); ++i) 
      it->addTo(retVal); 
     return retVal; 
    } 
    // and the base interface implementation 
    // (for other types implementation does not need to be some simple) 
    virtual void addTo(int& value) { value += mValue; } 
    virtual void addTo(long& value) { value += mValue; } 
    virtual void addTo(float& value) { value += mValue; } 
    virtual void addTo(double& value) { value += mValue; } 

private: 
    std::vector<std::shared_ptr<Base>> mFooVector; 
    // you can here ^^^^^^^^^^^^^^^^^ use simple Base* pointer but must 
    // then define d-tor, copy c-tor and assignment operator 
    T mValue; 
}; 
+0

太好了。謝謝,這回答了我的問題。然而,我認識到,在派生類中只聲明'virtual void addTo(T&value){...}'會使得它是抽象的,這是一個問題。但是我不滿意,要麼實現所有類型,因爲模板類沒有用。我仍在尋找。 – nenj

+0

@motjordet這些方法'addTo'不適用於你實現它的類(所以定義'addTo(T&)'沒有任何意義)。這些方法適用於其他的'Foo ',其中給定的'Foo '將出現在這個'Foo :: mFooVector'中。所以你必須爲每個可能的'U'定義'addTo(U&)'。當你不知道每個可能的'U'時,問題就開始了。在這種情況下,像C++這樣的靜態語言需要更復雜的解決方案。 – PiotrNycz

相關問題