2015-07-12 7 views
-2

У меня проблемы с моим кодом с dynamic_cast. Я потратил много часов, пытаясь найти решение для этого, но я до сих пор не нахожу ответа. Я читал, что проблема может быть в том, что я не писал декларации, но я уже сделал это и все еще с той же проблемой.Ошибка с dynamic_cast

Абстрактный класс

#include "CRoute.h" 

class CScreen 
{ 
protected: 

    CRoute* m_pRoute; 

public: 
    virtual ~CScreen(); 
    virtual void connecToRoute(CRoute* route) = 0; 
    virtual void drawRoute() = 0; 
}; 

производный класс

#include "CScreen.h" 

class CGUIScreen : public CScreen 
{ 

public: 
    void drawRoute(); 
    void connecToRoute(CRoute* route); 

}; 

производный класс

#include "CScreen.h" 
class CCRTScreen : public CScreen 
{ 
    public: 
     void drawRoute(); 
     void connecToRoute(CRoute* route); 

}; 

Базовый класс

#include <string> 
#include <iostream> 

using namespace std; 

class CScreen; 
class CCRTScreen; 
class CGUIScreen; 

class CWaypoint 
{ 
    public: 
     CWaypoint(); 
     void print(int format, CScreen* screenType); 

}; 

производный класс

#include <iostream> 
#include <string> 
#include "CWaypoint.h" 

using namespace std; 

class CScreen; 
class CCRTScreen; 
class CGUIScreen; 

class CPOI : public CWaypoint 
{ 
    public: 
     void print(int format, CScreen* screenType); 

}; 

Метод CPOI

void CPOI::print(int format, CScreen* screenType) 
{ 

    if(dynamic_cast<CGUIScreen*>(screenType)) ---> Here is the error <<---- 
    { 
     cout << "printing POI GUI " << endl; 
    } 

    else if(dynamic_cast<CCRTScreen*>(screenType)) ---> Here is the error <<---- 
    { 
     cout << "printing POI CRT " << endl; 
    } 
} 

И ошибки я получаю это следующий один

..\myCode\CWaypoint.cpp:184:41: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CGUIScreen*' (target is not pointer or reference to complete type) 
..\myCode\CWaypoint.cpp:184:44: error: expected unqualified-id before ')' token 
..\myCode\CWaypoint.cpp:188:46: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CCRTScreen*' (target is not pointer or reference to complete type) 
+2

Вы включили «# include» все необходимые заголовочные файлы для деклараций класса CScreen и производные классы, в которых вы применяете 'dynamic_cast <>'? –

+0

Да, все они – mrSatan

+1

Ошибки из файла CWaypoint.cpp, а не CPOI.cpp, как указывает ваш код! –

ответ

3

Я читал, что эта проблема может быть потому, что я не писал вперед заявления, но я уже сделал, что и до сих пор с той же проблема.

Совсем наоборот; ваши передовые декларации являются причиной ошибок.

Переслать декларацию, такую ​​как ваша строка class CScreen;, просто сообщает компилятору: «Существует класс под названием« CScreen ». Я дам вам более подробную информацию позже, но на данный момент просто имейте в виду, что это допустимое имя класса, ОК? "

Затем компилятор может сделать очень простые вещи с этим именем класса; например, он будет принимать с ним указательные или ссылочные объявления. Вот почему ваша линия print(int format, CScreen* screenType) работает. Вам не нужно ничего знать о CScreen, кроме его имени, чтобы объявить указатель на него.

Но как компилятор должен принять dynamic_cast с именем класса? Он ничего не знает о классе. В частности, он не знает, что CGUIScreen или CCRTScreen получены из CScreen. Вот почему в точке, где вы используете dynamic_cast, необходимы полные определения классов.

файлы заголовков для CWaypoint и CPOI (возможные называемые waypoint.h и point.h?), Таким образом, может безопасно использовать вперед деклараций. Как вы правильно сделали:

waypoint.h:

class CScreen; 
class CCRTScreen; 
class CGUIScreen; 

class CWaypoint 
{ 
    public: 
     CWaypoint(); 
     void print(int format, CScreen* screenType); 

}; 

point.h:

class CScreen; 
class CCRTScreen; // not necessary but not invalid 
class CGUIScreen; // not necessary but not invalid 

class CPOI : public CWaypoint 
{ 
    public: 
     void print(int format, CScreen* screenType); 

}; 

Файлы реализации, однако, (? Возможно называемые waypoint.cpp и point.cpp), требуют полных определений, когда вы используете dynamic_cast:

point.cpp:

#include "point.h" 
#include "screen.h" 
#include "gui_screen.h" 
#include "crt_screen.h" 

#include <iostream> 

using std::cout; 
using std::endl; 

void CPOI::print(int format, CScreen* screenType) 
{ 

    if(dynamic_cast<CGUIScreen*>(screenType)) 
    { 
     cout << "printing POI GUI " << endl; 
    } 

    else if(dynamic_cast<CCRTScreen*>(screenType)) 
    { 
     cout << "printing POI CRT " << endl; 
    } 
} 

Кстати, мне кажется, что CWaypoint должно быть на самом деле это абстрактный базовый класс, и что он, возможно, не нуждается в файл реализации на всех:

point.h:

class CScreen; 

class CWaypoint 
{ 
    public: 
     virtual ~CWaypoint() {} 
     virtual void print(int format, CScreen* screenType) = 0; 

}; 

P.S: Если я могу так сказать, я думаю, что ваши имена классов сбивают с толку. «Точка» определенно является чем-то более общим, чем «Путевая точка», но отношения наследования в точности противоположны. Также подумайте о том, чтобы избавиться от венгерской нотации. Просто позвоните своим классам Screen вместо CScreen и т. Д.

+0

Спасибо большое! В настоящее время работает! Как вы сказали, я должен добавить '# include' в мой класс' CPOI' – mrSatan

2

Что сообщение об ошибке говорит вам, что он делает не знаю, что такое определение CScreen или любого из производных классов, потому что вы заранее объявили их, но не включили их определения.

Вместо

class CScreen; 
class CCRTScreen; 
class CGUIScreen; 

Использование

#include "CCRTScreen.h" 
#include "CGUIScreen.h" 
+1

Это не работает, я получаю еще больше ошибок .... – mrSatan

+0

@mrSatan Ну, вам нужны полные типы, поэтому вам нужно выяснить, как исправить другие ошибки. – juanchopanza

+0

Если вы используете MS, добавьте ** # pragma once ** в свои включенные файлы. Если вы используете Linux, добавьте ** # ifndef .. # endif ** guards – cup

Смежные вопросы