dynamic_cast出错

时间:2015-07-12 09:36:22

标签: c++ casting abstract-class

我在使用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 个答案:

答案 0 :(得分:3)

  

我读到问题可能是因为我没有向前写   声明,但我已经做了同样的事情   问题

恰恰相反;你的前瞻性声明是造成错误的原因。

前向声明,例如你的class CScreen;行,只是告诉编译器:“有一个名为'CScreen'的类。我稍后会给你更多详细信息,但现在只需保留请注意,这是一个有效的类名,好吗?“

然后编译器可以使用该类名做非常基本的事情;例如,它将接受指针或引用声明。这就是你的print(int format, CScreen* screenType)行有效的原因。除了名称之外,您不需要知道CScreen以外的任何内容来声明指向它的指针。

但编译器如何接受带有类名的dynamic_cast?它对课程一无所知。特别是,它不知道CGUIScreenCCRTScreen来自CScreen。这就是为什么在使用dynamic_cast时,需要完整的类定义。

CWaypointCPOI(可能称为waypoint.hpoint.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.cpppoint.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"