2014-02-14 56 views
0

我有一個類轉換爲基地的問題。 這是代碼:C++ autoconvert繼承類到基類

#define Derive_NTag_CRTP(Type) class Type: public NTagBase<Type> 

template<typename Derived> 
class NTagBase{ 
public: 
    NTagBase(var name) { this->_name = name; } 
    NTagBase(const NTagBase & ntag) { this->_name = ntag._name; } 
    NTagBase* append(NTagBase<Derived> *item) { _children.push_back(item); return this; } 
private: 
    var _name; 
    vector<NTagBase *> _children; 
}; 

Derive_NTag_CRTP(NTag){ 
public: 
    NTag(var name) : NTagBase(name) { } 
    NTag(const NTagBase & ntag) : NTagBase(ntag) { } 
}; 

Derive_NTag_CRTP(NTagInput){ 
public: 
    NTagInput(var type) : NTagBase("input") { _type = type; } 
    NTagInput(const NTagBase & ntag) : NTagBase(ntag) { } 
private: 
    var _type; 
}; 


int main(int argc, char **argv, char **envv) 
{ 

    NTag div("div"); 
    NTagInput button("button"); 
    div.append(new NTag("span")); 

    div.append(&button);// Error 1 error C2664: 'NTagBase<Derived>::append': can not convert parameter 1 from 'NTagInput *' to 'NTagBase<Derived> *' 

    } 

我該如何解決,如果沒有做一個明確的投? PS:我需要有一個基類指針向量,並追加到所有繼承的類中。

+0

你想'矢量 _children'? (以避免可能的切片) – Jarod42

+0

我想追加一個按鈕對象到div,但按鈕對象是NTagInput,而不是NTagBase – pava91

+0

順便說一句:'NTagInput'(':public NTagBase ')與'NTagBase '不同。 NTagBase可能來自一個共同的基礎,以允許你想要的東西。 – Jarod42

回答

0

divNTag,即NTagBase<NTag>buttonNTagInput,即NTagBase<NTagInput>,而divappend()預計與NTagBase<NTag>無關。你應該改變append到類似

template <typename D> 
NTagBase* append(NTagBase<D> item) { ... } 

但是,你仍然不能存儲在一個單一的載體不同類型的項目。最好製作一個非模板例如BaseNTagBase並讓您的向量包含指針(或std::unique_ptr)至Base

+0

我用矢量指針和append方法的typename更新了代碼。但我仍然得到錯誤。 – pava91

+0

@ pava91你應該使'append'成爲一個模板函數,或者讓它接受一個指向普通(可能是非模板)基類的指針/引用。它仍然期待錯誤的論點類型。 – iavr

0

div.append (...)顯然需要重載,因爲從基地繼承後,它不會理解第二個簽名,例如div.append(&button);,或者您可以創建一個包裝類,將每個對象類型打包到它自己的定義並提供一個反向返回機制到原來的類型。

另外,只需重載任何必要的功能。

class NTagInput; 
class AppendInputRegister; 


template<typename Derived> 
class NTagBase{ 
    public: 
     NTagBase(string name) { this->_name = name; } 
     NTagBase(const NTagBase & ntag) { this->_name = ntag._name; } 
     NTagBase* append(NTagBase<Derived> *item) { 
      _children.push_back((NTagBase *)item); 
       return this; 
     } 
    private: 
     string _name; 
     vector<NTagBase *> _children; 
}; 

class NTag: public NTagBase<NTag>{ 
    public: 
     NTag(string name) : NTagBase(name) { } 
     NTag(const NTagBase & ntag) : NTagBase(ntag) { } 

     NTagBase* append(NTagBase<NTagInput> *item) { 
      append((NTagBase<NTag> *)item); 
     } 

     NTagBase* append(NTagBase<NTag> *item) { 
      NTagBase::append((NTagBase<NTag> *)item); 
     } 

}; 

class NTagInput: public NTagBase<NTagInput>{ 
    public: 
     NTagInput(string type) : NTagBase("input") { _type = type; } 
     NTagInput(const NTagBase & ntag) : NTagBase(ntag) { } 
    private: 
     string _type; 
};