我目前正处于学校项目的中间,我必须翻译"翻译"一个Java程序到C ++。
该程序模拟媒体库并使用继承。基本上,您有一个可以添加项目的媒体库。您可以添加的各种项目包括书籍,电影和MusicAlbums。
我有一个类库,它主要创建一个实例,并且有一个容器来容纳我的所有项目。 Item是超类,Book,Movie和MusicAlbum是它的派生类。
我在这里遇到从Java转换为C ++的问题:
我的导师提供了#34; Main.cpp",我必须基于此编写程序的其余部分。我不被允许修改它或者作业无效。然而," Main.cpp"呼叫
cout << item << endl;
每次将项目添加到媒体库。所以,那当然把它发送到Item.cpp,我已经覆盖了&lt;&lt;&lt;&lt;&lt;&lt;操作
现在,我必须弄清楚是否&#34;项目&#34;在我编写用于输出数据的代码之前,它是Book,Movie或MusicAlbum,因为这些内容中的每一个都需要以不同的方式打印。
在我的Java程序中,我写了类似的东西:
if(item instanceof Book){
System.out.println((Book) item); // I overrode "toString" in Book.Java
}
elseif(item instanceof Movie){
System.out.println((Movie) item); // overwrode "toString" in Movie.java
}
else
{
System.out.println((MusicAlbum) item; // overrode "toString" in MusicAlbum.java
正如您所看到的,我使用instanceof来确定它是哪种类型的项目,然后在将项目传递给println之前将项目转换为该派生类型,然后重写所有派生类&#39; s&#34 ;的toString&#34;方法
我不知道如何在C ++中这样做。我已经在stackoverflow和其他论坛上看了很多类似的问题,他们都建议我尝试过但没有工作的东西,或者他们告诉你如何将项目转换为派生类型而不是如何只是 - 检查 - 它是什么派生类型,而不是先实际改变它。
如果有人对C ++的工作原理有任何了解,我将非常感激。谢谢。
答案 0 :(得分:2)
通过使用dynamic_cast<T>
,您可以尝试强制转换为派生类指针。如果成功,那就是正确的类型。如果它失败了,那就不是了。
if( dynamic_cast<Book*>(item) ) { // stuff }
C ++确实提供了有限的编译时间方法来检查某些事情。例如,您可以检查某些内容是否为派生类
std::is_base_of<base, derived>
还有std::is_same<type1, type2>
问题是这些是编译时间分辨率。运行时多态性意味着你无法在运行时真正知道你的具体类型是什么。
编辑:添加一些可能对您的情况更有用的信息。
行cout << item << endl;
,你正在做的事情不会从我能说的来解决你的问题。动态类型识别无论如何都是糟糕的设计,你应该一般避免它。
不,在这种情况下你需要利用多态性。你想要operator<<
虚拟。您的子类将有自己的打印数据方式。
调用cout << item << endl;
时,您无需弄清楚类型。 vtable查找将为您完成,您将获得所需的行为。
唯一的问题是你可能需要在重载和免费operator>>
之间建立一个中间人。基本上你会有一个像我提到的虚拟运算符,但是你需要一个重载来确保正确调用它,因为它是一个类成员而不是一个自由函数。
答案 1 :(得分:0)
您倾向于使用dynamic_cast
运算符。
Book* book = dynamic_cast<Book*>(item);
if (book != nullptr) {
cout << book->toString() << endl;
}
还有typeid(item)
将为您提供type_info
结构,您可以在其中进行比较,但更有效的方法是执行类型转换。即使你要求不进行类型转换,C ++也不是Java - 你不应该期望相同的编程方法。类型转换只是在C ++中实现它的理想方式。