我在使用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);
};
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)
答案 0 :(得分: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:如果我可以这样说,我认为你的班级名字令人困惑。 “点”肯定比“Waypoint”更通用,但继承关系恰恰相反。另外,考虑摆脱匈牙利表示法。只需拨打您的课程Screen
,而不是CScreen
等。
答案 1 :(得分:2)
错误消息告诉您的是,它不知道CScreen或任何派生类的定义是什么,因为您已经向前声明了它们但未包括它们的定义。
而不是
class CScreen;
class CCRTScreen;
class CGUIScreen;
使用
#include "CCRTScreen.h"
#include "CGUIScreen.h"