2016-12-11 60 views
1

我目前正處於一個學校項目的中間,在這個項目中,我必須將Java程序「翻譯」爲C++。什麼是Java的instanceof的C++版本? :檢查,而不是鑄造

該程序模擬媒體庫並使用繼承。基本上,你有一個媒體庫,你可以添加項目。您可以添加的不同種類的項目是書籍,電影和MusicAlbums。

我有一個類庫,主要創建一個實例,並有一個容器來容納我所有的物品。 Item是超類,Book,Movie和MusicAlbum是它的派生類。

這裏就是我在翻譯從Java到C++的問題:

我的教師提供「Main.cpp的」,我必須編寫基於關閉的,該計劃的其餘部分。我不允許修改它或分配無效。但是,每次將項目添加到媒體庫時,「Main.cpp」調用

cout << item << endl; 

。所以,當然這會將它發送到Item.cpp,我已經覆蓋了運算符< <。

現在,在編寫用於輸出其數據的代碼之前,我必須能夠弄清楚「item」是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來確定這是哪種類型的項目,然後我才通過投的項目是派生類型它在覆蓋所有派生類的「toString」方法之後進行println。

我不知道如何在C++中做到這一點。我已經看了很多關於stackoverflow和其他論壇的類似問題,他們都提出了我嘗試過但沒有用的東西,或者他們告訴你如何將項目轉換爲派生類型,但不知道如何去檢查 - 它的派生類型沒有實際先改變它。

如果有人對C++中的工作方式有所瞭解,我將非常感激。謝謝。

+0

你可以使用['dynamic_cast' !!(http://en.cppreference.com/w/cpp/language/dynamic_cast)。雖然演員通常被視爲不良設計的指示,並增加運行成本。 –

+0

在您的Java示例中,檢查'instanceof' od'item'並將其轉換爲'Book'或'Movie'或'MusicAlbum'是沒有意義的。 'System.out.println(item)'無論如何都會調用overriden方法。 – lexicore

+0

謝謝P.R.,謝謝你@lexicore指出這一點。這個類是一種java/c + +混合體,是我第一次使用Java,所以我是一個總新手 – BabaSvoloch

回答

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>>之間的中間人。基本上你會像我提到的那樣擁有一個虛擬操作符,但是你需要重載,以確保它是正確調用的,因爲它是一個類成員而不是自由函數。

Look here for details

+0

這工作!謝謝 – BabaSvoloch

0

您會傾向於使用dynamic_cast運算符。

Book* book = dynamic_cast<Book*>(item); 
if (book != nullptr) { 
    cout << book->toString() << endl; 
} 

還有typeid(item),這將給你一個type_info結構,其中你可能做一個比較,但更有效的方式來做到這一點是進行類型轉換。即使你要求不要進行類型轉換,C++不是Java--你不應該期待相同的編程方法。類型轉換隻是在C++中實現它的理想方式。

+0

值得注意的是,有些編譯器需要按順序打開RTTI(運行時類型信息)使用這樣的功能。 – Mitch