Я новичок в С++. У меня есть два чистых абстрактных класса (например, интерфейсы), и я получаю класс из этих двух чистых абстрактных классов.
В одном случае мне нужно преобразовать указатель производного класса в один из базовых абстрактных классов. Прежде всего, есть ли какие-либо ограничения на это.
class IBase1
{
virtual ~IBase() = default;
}
class IBase2
{
virtual ~IBase2() = default;
}
class Derived : public IBase, public IBase2
{
}
Derived d;
IBase1* basePtr = dynamic_cast<IBase1*>(&d);
Здесь, если я использую любое другое приведение, я не совсем уверен, но я получаю неверный указатель от приведения, поэтому мне нужно использовать dynamic_cast для повышения приведения из множественного наследования, верно?
Когда я это делаю, я получаю сообщение об ошибке «исходный тип не полиморфен».
Мои базовые классы являются чистыми абстрактными классами, поэтому у них есть по крайней мере один виртуальный метод, так что все должно быть в порядке, верно, но почему я получаю эту ошибку? Это о множественном наследовании?
Редактировать: здесь есть еще один слой. Мой производный класс должен содержать экземпляры двух разных типов, но мои экземпляры действительно очень большие переменные, поэтому, как разработчик C :), я планировал использовать Union для меньшего использования памяти. Объединение имеет только экземпляры двух классов, которые являются производными от чистых абстрактных классов. Итак, я предполагал, что адрес экземпляра объединения также должен указывать смещения экземпляров моего класса, но С++, вероятно, не может знать адрес методов записи членов.
class IFile
{
public:
virtual ~IFile() = default;
};
class IDirectory
{
public:
virtual ~IDirectory() = default;
};
class FileSystem1 : public IFile, public IDirectory
{
public:
FileSystem1() { }
virtual ~FileSystem1() final override = default;
private:
Native1APIInstance file;
};
class FileSystem2 : public IFile, public IDirectory
{
public:
FileSystem2() { }
virtual ~FileSystem2() final override = default;
private:
Native2APIInstance file;
};
union FileSystemInstance
{
FileSystem1 fs1;
FileSystem2 fs2;
FileSystemInstance(string path)
{
if (path[0] == '1') // initialise fs1
else if (path[0] == '2') // initialise fs2
}
};
FileSystem fs("<PATH to File System>");
IFile* file = reinterpret_cast<IFile*>(&fs);
Здесь я не хочу интересоваться, какой экземпляр инициализируется. Я хочу работать только с интерфейсом базового класса. Мне интересно, это как-то возможно с Союзом?
Спасибо.
Derived
уже относится к типуIBase
, аDerived*
преобразуется вIBase*
(обратное неверно). Кроме того, после исправления множества опечаток я не могу воспроизвести проблему - person Yksisarvinen   schedule 15.10.2019dynamic_cast
в данном случае не нужен.IBase* basePtr = &d
будет работать нормально. Вам нужен динамический бросок при переходе от базового к производному. - person cplusplusrat   schedule 15.10.2019IFile* file = &fs.fs1
- person rustyx   schedule 15.10.2019int
илиchar
, и для вещей низкого уровня. - person Phil1970   schedule 15.10.2019