2016-12-11 3 views
1

저는 현재 Java 프로그램을 C++로 "번역"해야하는 학교 프로젝트의 한가운데에 있습니다.Java의 instanceof의 C++ 버전은 무엇입니까? : 캐스팅이 아닌 체크

프로그램이 미디어 라이브러리를 에뮬레이트하고 상속을 사용합니다. 기본적으로 항목을 추가 할 수있는 미디어 라이브러리가 있습니다. 추가 할 수있는 항목의 종류는 책, 영화 및 MusicAlbum입니다.

나는 주 라이브러리가의 인스턴스를 만들고, 모든 항목을 보유 할 컨테이너가있는 라이브러리가 있습니다. Item은 수퍼 클래스이며 Book, Movie 및 MusicAlbum은 파생 클래스입니다. 나는 자바에서 C++로 변환하는 문제에 봉착 경우 여기

는 다음과 같습니다

내 강사는 "하여 Main.cpp을"제공을, 나는 그 기반으로 프로그램의 나머지 부분을 작성해야합니다. 수정할 수 없거나 배정이 잘못되었습니다. 그러나 "Main.cpp"는 미디어 라이브러리에 항목을 추가 할 때마다

cout << item << endl; 

을 호출합니다. 그래서, 당연히 Item.cpp로 보내어 여기서 < < 연산자를 재정의했습니다.

이제 데이터를 출력하기위한 코드를 작성하기 전에 해당 항목이 책, 영화 또는 MusicAlbum인지 여부를 파악할 수 있어야합니다. 각 항목을 다르게 인쇄해야하기 때문입니다. 당신이 볼 수 있듯이 나는 그것이 항목의 유형을 결정하기 위해 instanceof를 사용,

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 

하고 나는 전달하기 전에 그 파생 유형으로 항목을 캐스트 : 내 자바 프로그램에서

, 내가 뭔가를 썼다 파생 클래스의 toString 메소드를 모두 오버라이드 (override) 한 후, println를 호출합니다.

C++에서이 작업을 수행하는 방법을 모르겠습니다. stackoverflow 및 다른 포럼에서 비슷한 질문을 많이 보았습니다. 모두 시도했거나 작동하지 않는 항목을 제안하거나 항목을 파생 된 유형으로 캐스팅하는 방법을 알려주지 만 확인 방법은 제시하지 않습니다. - 파생 된 유형은 실제로 먼저 변경하지 않고 있습니다.

누구나 C++에서 어떻게 작동하는지에 대한 통찰력이 있다면 매우 감사 할 것입니다. 고맙습니다.

+0

당신은 사용할 수 있습니다 ['dynamic_cast'!] (http://en.cppreference.com/w/cpp/language/dynamic_cast). 캐스트는 일반적으로 잘못된 디자인을 나타내는 것으로 보이지만 런타임 비용이 추가됩니다. –

+0

'instanceof' od'item'을 검사하여'Book' 또는'Movie' 또는'MusicAlbum'으로 캐스팅하는 것은 자바 예제에서 의미가 없습니다. 'System.out.println (item)'은 어쨌든 재정의 메소드를 호출합니다. – lexicore

+0

감사합니다. P.R., 그리고 지적 해 주셔서 감사합니다. @lexicore. 이 클래스는 Java/C++ 하이브리드의 일종이며 처음으로 Java를 사용한 적이 있으므로 전체 초보자입니다 – BabaSvoloch

답변

2

dynamic_cast<T>을 사용하면 파생 클래스 포인터로 캐스팅을 시도 할 수 있습니다. 성공하면 올바른 유형입니다. 실패하면, 그렇지 않습니다.

if(dynamic_cast<Book*>(item)) { // stuff }

C++는 어떤 일을 확인하기 위해 제한 컴파일 시간의 방법을 제공한다.뭔가 문제도 std::is_same<type1, type2>

있습니다 std::is_base_of<base, derived>

와 파생 클래스 인 경우 예를 들어, 다음은 컴파일 시간 해상도 때문이다 확인할 수 있습니다. 런타임 다형성이란 자연스럽게 런타임 전에 실제 유형을 정확히 알 수 없음을 의미합니다.

편집 : 상황에 더 유용한 정보를 추가하십시오.

라인 cout << item << endl;, 당신이하고있는 일은 내가 말할 수있는 것에서 당신의 문제를 해결하지 않을 것입니다. 동적 유형 식별은 어쨌든 나쁜 설계이므로 일반적으로 사용하지 않아야합니다.

아니요, 대신이 경우 다형성을 활용해야합니다. operator<< 가상으로 설정하려고합니다. 서브 클래스는 데이터를 인쇄하는 고유 한 f}을 갖습니다.

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; 
} 

또한 당신에게 당신이 가능하게 비교를 할 수있는 type_info 구조,하지만 유형 캐스트를 수행하는 것입니다 할 수있는보다 효율적인 방법을 제공합니다 typeid(item) 있습니다. 당신이 타입 캐스트를하지 말 것을 요구 했음에도 불구하고, C++은 자바가 아닙니다 - 당신은 같은 프로그래밍 방법을 기대해서는 안됩니다. 형식 캐스트는 단순히 C++에서 원하는 형식입니다.

+0

일부 컴파일러는 RTTI (런타임 유형 정보)를 순서대로 켜야 할 필요가 있습니다 그러한 기능을 사용합니다. – Mitch