c ++ autoconvert继承类到基类

时间:2014-02-14 11:05:25

标签: c++

我将一个类转换为base有一个问题。 这是代码:

    #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:我需要有一个基类指针向量,并附加到继承的所有类中。

2 个答案:

答案 0 :(得分:0)

divNTag,即NTagBase<NTag>buttonNTagInput,即NTagBase<NTagInput>,而div的{​​{1}}期望append()不相关。您应该将NTagBase<NTag>更改为

append

但是,您仍然无法在单个矢量中存储不同类型的项目。最好制作一个非模板,例如template <typename D> NTagBase* append(NTagBase<D> item) { ... } 的{​​{1}}并让您的向量包含指针(或Base)到NTagBase

答案 1 :(得分: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;
};