简体   繁体   中英

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. 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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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