перегрузка чисто виртуальных функций и ковариантные возвращаемые типы с множественным унаследованием

Я должен пересмотреть мой предыдущий вопрос. Существуют ли какие-либо ограничения для ковариантных типов возвращаемых данных, создаваемых с множественным наследованием?

Код ниже представляет проблему. Если мы раскомментируем наследование класса IDFOutputPin от IDFP во всем коде, то мы пытаемся получить IDFOutputPin через интерфейс IDFSourceNode от объекта типа Source. Вопрос, почему так происходит? Я только начал использовать шаблоны и такие миксины, так что, возможно, для этого есть какое-то ограничение, или, может быть, это ошибка компилятора — 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 multpile inharitance

return 0;
}

1

Решение

Я не могу воспроизвести вашу проблему. Следующий код прекрасно работает для меня и, кажется, делает то, что вы хотите:

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

Вы можете даже украсить все, кроме первого get с override virt-спецификатор, если у вас есть C ++ 11.

2

Другие решения

Других решений пока нет …