【发布时间】:2019-10-14 21:11:57
【问题描述】:
我是 C++ 的新手。 我有两个纯抽象类(如接口),我从这两个纯抽象类派生一个类。
在某种情况下,我需要将派生类指针向上转换为基础抽象类之一。 首先,有没有限制。
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 来减少内存使用量。 联合只有从纯抽象类派生的两个类的实例。所以,我假设联合实例地址也应该指向我的类实例的偏移量,但是 C++ 不可能知道写入成员方法的地址。
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);
在这里,我不想关心初始化了哪个实例。我只想使用基类接口。我想知道联盟是否有可能?
谢谢。
【问题讨论】:
-
修复代码,让它显示问题,而不是一堆拼写错误。
-
你不需要 any 演员表。
Derived已经是IBase类型,而Derived*可以转换为IBase*(反之则不然)。另外,在修正了很多错别字之后,I cannot reproduce the problem -
dynamic_cast在这种情况下不需要。IBase* basePtr = &d可以正常工作。从基础到派生时,您需要动态转换。 -
如果你真的需要将你的对象向上转换为它的基类,你也应该重新考虑你的设计。
-
@Jens 我认为你的意思正好相反。向上转换多态类型很常见;它是硬编码的向下转换,通常表示设计错误。
标签: c++ multiple-inheritance dynamic-cast upcasting