简体   繁体   English

具有多重继承的纯虚函数重载和协变返回类型

[英]pure virtual functions overloading and covariant return types with multiple inheritance

I have to revise my previous question.我必须修改我之前的问题。 Are there any limitations for covariant return types to be created with multiple inheritance?使用多重继承创建协变返回类型是否有任何限制?

Code below presents the problem.下面的代码提出了问题。 If we uncomment for class IDFOutputPin inheritance from IDFPin the whole code breaks when we try to get IDFOutputPin through IDFSourceNode interface from object of type Source.如果我们取消对 IDFOutputPin 类从 IDFPin 继承的注释,当我们尝试通过 IDFSourceNode 接口从 Source 类型的对象获取 IDFOutputPin 时,整个代码就会中断。 Question why is it happening like this?问题为什么会这样? I have just started to use templates and such mixins so perhaps there is some limitation for that or maybe it is compilers fault - VS2010?我刚刚开始使用模板和这样的 mixin,所以可能有一些限制,或者可能是编译器错误 - VS2010?

class PinBase {};
class Pin : public PinBase {};
class OutputPin : public Pin {};
class ExtOutputPin : public OutputPin {};
class IDFPin {};
class IDFOutputPin : /*public IDFPin,*/ public ExtOutputPin {}; // <---- when we uncomment this line part our covariant return type is created through multiple inharitance and the code breaks - question WHY?
class CustomDFPin : public IDFOutputPin {};

class Node {};
class IDFNode : public virtual Node {};

class ISourceNode : public virtual Node
{
public:
    virtual OutputPin * get(int idx)  = 0;
};

class IDFSourceNode : public virtual IDFNode, public virtual ISourceNode
{
public:
    virtual IDFOutputPin * get(int idx) = 0;
};

template<class Pin, class Node>
class NodeImpl
{
public:
    typedef std::vector<Pin*> Pins;

public:

    void addPin(Pin * pin)
    {
        pins_.push_back(pin);
    }

    void removePin(Pin * pin)
    {
        std::remove(pins_.begin(), pins_.end(), pin);
    }

    Pin * pin(int idx) { return pins_[idx]; }
    const Pin * pin(int idx) const { return pins_[idx]; }

private:
    Pins pins_;
};

template<class OPin = Pin, class Interface = ISourceNode>
class SourceNode : public virtual Interface
{
protected:

    void addPin(OPin * pin)
    {
        pins_.addPin(pin);
    }

public:
    virtual OPin * get(int idx)
    {
        return pins_.pin(idx);
    }

private:
    NodeImpl<OPin, SourceNode<OPin, Interface>> pins_;
};

template<class OPin = DFPin, class Interface = IDFSourceNode>
class DFSourceNode : public SourceNode<OPin, Interface>
{

};

class Source : public DFSourceNode<CustomDFPin>
{
public:
    Source()
    {
        addPin(new CustomDFPin());
    }
};



int main( int argc, char **argv)
{
    Source * tmp = new Source();
    IDFSourceNode * tmpB = tmp;
    CustomDFPin * pin = tmp->get(0);
    IDFOutputPin * pinB = tmpB->get(0); //this call here calls pure virtual function if I am not wrong, exception is thrown when IDFOutputPin is created through multiple inheritance

    return 0;
}

I cannot reproduce your problem.我无法重现您的问题。 The following code works fine for me and seems to do what you want:以下代码对我来说很好用,似乎可以做你想做的事:

struct A { };
struct B : A { };

struct Foo
{
    virtual A * get() = 0;
};

struct Bar : Foo
{
    virtual B * get() = 0;
};

struct Zip : Bar
{
    //virtual A * get() { return nullptr; }  // Error, as expected
    virtual B * get() { return nullptr; }
};

int main()
{
    Zip x;
}

You can even decorate all but the first get with the override virt-specifier if you have C++11.如果您有 C++11,您甚至get使用override virt-specifier 装饰除第一个get所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM