2016-12-11 5 views
1

Я сейчас в середине проекта для школы, в котором я должен «перевести» Java-программу на C++.Что такое C++ версия экземпляра Java? : проверка, а не литье

Программа эмулирует медиа-библиотеку и использует наследование. В принципе, у вас есть медиа-библиотека, к которой вы можете добавить элементы. Различные предметы, которые вы можете добавить, - это книги, фильмы и музыкальные альбомы.

У меня есть библиотека классов, главная из которых создает экземпляр и у которого есть контейнер для хранения всех моих элементов. Элемент - это суперкласс, а Book, Movie и MusicAlbum - его производные классы.

Вот где у меня возникли проблемы перевода с Java на C++:

Мой инструктор предоставил «main.cpp», и я должен написать остальную часть программы, основанной от этого. Мне не разрешено изменять его, или присваивание недействительно. Однако «Main.cpp» вызывает

cout << item << endl; 

каждый раз, когда он добавляет элемент в медиа-библиотеку. Таким образом, это, конечно, отправляет его в Item.cpp, где я переопределил оператор < <.

Теперь я должен выяснить, является ли этот «элемент» книгой, фильмом или 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, после переопределения всех методов «toString» производного класса.

Я не знаю, как это сделать на C++. Я просмотрел множество похожих вопросов на stackoverflow и других форумах, и все они либо предлагают вещи, которые я пробовал и не работали, либо они рассказывают вам, как отличать элемент от производного типа, но не как просто -check - какой производный тип он не меняет сначала.

Если у кого-то есть представление о том, как это будет работать на C++, я был бы очень благодарен. Спасибо.

+0

Вы можете использовать [ 'dynamic_cast' !!] (http://en.cppreference.com/w/cpp/language/dynamic_cast). Хотя броски обычно воспринимаются как индикаторы плохого дизайна и приходят за добавленную стоимость исполнения. –

+0

Проверка 'instanceof' od' item' и отбрасывание его на 'Book' или' Movie' или 'MusicAlbum' не имеет смысла в вашем примере Java. 'System.out.println (item)' все равно вызовет метод overriden. – lexicore

+0

Спасибо П. Р., и спасибо тоже @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>

Проблема заключается в том, что эти компиляции резолюции времени. Runtime-полиморфизм означает, что вы не можете по-настоящему узнать перед временем выполнения, каковы ваши конкретные типы.

Редактировать: добавление некоторой информации, которая, вероятно, более полезна для вашей ситуации.

Линия 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 - вы не должны ожидать того же метода программирования. Тип cast - это просто желаемый способ сделать это на C++.

+0

Стоит отметить, что некоторым компиляторам необходимо будет включить RTTI (информацию о времени выполнения), чтобы использовать такую ​​функциональность. – Mitch