Не может бросить класс со множественным наследованием

Я пытаюсь осуществить рефакторинг некоторый код при отъезде существующей функциональности в такте. Я испытываю затруднения при кастинге указателя на объект в основной интерфейс и затем выводе производного класса позже. Программа использует объект фабрики для создания экземпляров этих объектов в определенных случаях.

Вот некоторые примеры классов, с которыми я работаю.

// This is the one I'm working with now that is causing all the trouble.
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I
// used virtual inheritance.
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... }

// This is what it looked like before
class MyObject : public OldAbstract { ... }

// This is an example of most other classes that use the base interface
class NormalObject : public ISerializable

// The two abstract classes. They inherit from the same object.
class NewAbstract : public ISerializable { ... }
class OldAbstract : public ISerializable { ... }

// A factory object used to create instances of ISerializable objects.
template class Factory
{
public:
    ...
    virtual ISerializable* createObject() const
    {
        return static_cast(new T()); // current factory code
    }
    ...
}

Этот вопрос имеет хорошую информацию о том, что делают различные типы кастинга, но это не помогает мне выяснить эту ситуацию. Используя static_cast и регулярный кастинг дают мне error C2594: 'static_cast': ambiguous conversions from 'MyObject *' to 'ISerializable *'. Используя dynamic_cast заставляет createObject () возвращать ПУСТОЙ УКАЗАТЕЛЬ. NormalObject разрабатывают классы и старую версию работы MyObject с существующим static_cast на фабрике.

Существует ли способ заставить этот бросок работать? Кажется, что это должно быть возможно.

5
задан Community 23 May 2017 в 12:16
поделиться

4 ответа

Вы должны виртуально унаследовать от ISerializable (я только что тестировал его с VS2010). Это обычная проблема, называемая Алмазная проблема , когда компилятор не знает, какой иерархический путь выбрать.

РЕДАКТИРОВАТЬ:

Это должно сработать:

class NewAbstract : public virtual ISerializable { ... } 
class OldAbstract : public virtual ISerializable { ... } 
10
ответ дан 14 December 2019 в 01:02
поделиться

Вы можете обойти это, применив сначала к одной из ваших непосредственных баз, например.

virtual ISerializable* createObject() const
{
    NewAbstract*const na = dynamic_cast< NewAbstract* >( new T() );
    return dynamic_cast< ISerializable* >( na );
}
1
ответ дан 14 December 2019 в 01:02
поделиться

Найдите «ужасный алмаз» и виртуальное наследование. Они могут вам помочь.

-2
ответ дан 14 December 2019 в 01:02
поделиться

Не наследуют виртуально и от NewAbstract, и от OldAbstract. Выберите тот, от которого хотите унаследовать виртуально. Я думаю, что это может решить эту проблему.

0
ответ дан 14 December 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: