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

问题描述 投票:1回答:1

我必须修改我先前的问题。使用多重继承创建协变返回类型是否有任何限制?

下面的代码提出了问题。如果我们取消从IDFP中继承类IDFOutputPin的注释,则当我们尝试从Source类型的对象通过IDFSourceNode接口获取IDFOutputPin时,整个代码就会中断。问题为什么会这样发生?我刚刚开始使用模板和此类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;
}
c++ inheritance virtual covariant
1个回答
2
投票

我无法重现您的问题。以下代码对我来说很好用,似乎可以满足您的要求:

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;
}

如果您有C ++ 11,甚至可以用get virt-specifier装饰除第一个override以外的所有字符。

© www.soinside.com 2019 - 2024. All rights reserved.