C++ C++;派生列表中的作用域运算符

C++ C++;派生列表中的作用域运算符,c++,inheritance,polymorphism,nested-class,C++,Inheritance,Polymorphism,Nested Class,我在WinImp.h中得到一个错误,它说“Root”尚未声明。如果我不使用作用域运算符(class-WinImp:public-BaseDef),错误是error:required-class-name在“{”标记之前。有人知道为什么会发生这种情况吗 根 class Root { public: class BaseDef { public: virtual void foo() = 0;

我在WinImp.h中得到一个错误,它说
“Root”尚未声明。如果我不使用作用域运算符(
class-WinImp:public-BaseDef
),错误是
error:required-class-name在“{”标记之前。有人知道为什么会发生这种情况吗

class Root {
    public:
        class BaseDef {
            public:
                virtual void foo() = 0;
                virtual void bar() = 0;
        };
    private:
        #ifdef _WIN32
        friend class WinImp;
        #else
        friend class NixImp;
        #endif

        BaseDef* imp;

        BaseDef* getImp();

    public:
        Root() : imp(getImp()) {}
        void foo();
        void bar();
};
Root.cpp

#include "Root.h"
void Root::foo() {
    imp->foo();
}

void Root::bar() {
    imp->bar();
}
温尼普

#ifdef _WIN32
#include "Root.h"
class WinImp : public Root::BaseDef {
    public:
        void foo();
        void bar();
};
#endif
WinImp.cpp

#include "WinImp.h"
#ifdef _WIN32
    void WinImp::foo() {

    }

    void WinImp::bar() {

    }

    Root::BaseDef* Root::getImp() {
        return static_cast<BaseDef*>(new WinImp());
    }
#endif
#包括“WinImp.h”
#ifdef_WIN32
void WinImp::foo(){
}
void WinImp::bar(){
}
Root::BaseDef*Root::getImp(){
返回静态_cast(新的WinImp());
}
#恩迪夫

您正在根目录下访问
BaseDef
接口,因此它们应该是公共的:

class BaseDef 
{
 public:
   virtual void foo() = 0;
   virtual void bar() = 0;
};
在WinImp.cpp中,
foo()、bar()
需要返回类型,并且它们不在根范围内,应该是:

void WinImp::foo() { }
void WinImp::bar() { }

您正在根目录中访问
BaseDef
接口,因此它们应该是公共的:

class BaseDef 
{
 public:
   virtual void foo() = 0;
   virtual void bar() = 0;
};
在WinImp.cpp中,
foo()、bar()
需要返回类型,并且它们不在根范围内,应该是:

void WinImp::foo() { }
void WinImp::bar() { }

WinImp.cpp
修复为如下所示:

#include "WinImp.h"
#ifdef _WIN32
    // WinImp is not scoped within Root
    void WinImp::foo() {

    }

    void WinImp::bar() {

    }

    Root::BaseDef* Root::getImp() {
        return dynamic_cast<BaseDef*>(new WinImp());
    }
#endif
#包括“WinImp.h”
#ifdef_WIN32
//WinImp的作用域不在根目录中
void WinImp::foo(){
}
void WinImp::bar(){
}
Root::BaseDef*Root::getImp(){
返回动态_cast(新的WinImp());
}
#恩迪夫

Fix
WinImp.cpp
如下所示:

#include "WinImp.h"
#ifdef _WIN32
    // WinImp is not scoped within Root
    void WinImp::foo() {

    }

    void WinImp::bar() {

    }

    Root::BaseDef* Root::getImp() {
        return dynamic_cast<BaseDef*>(new WinImp());
    }
#endif
#包括“WinImp.h”
#ifdef_WIN32
//WinImp的作用域不在根目录中
void WinImp::foo(){
}
void WinImp::bar(){
}
Root::BaseDef*Root::getImp(){
返回动态_cast(新的WinImp());
}
#恩迪夫

因为
BaseDef
的命名空间可见性限制为
Root
。您必须限定其命名空间才能访问它。此外,您不应该在
WinImp::foo()和
WinImp::bar()前面使用
Root::
definitions。Unrelated:不要将
dynamic\u cast
用于向上播放。仅在向下播放时使用它,并且仅当您不确定播放是否会成功时(因为动态类型未知)实际上,您正在检查强制转换的返回值是否为
!=nullptr
。在已知动态类型的情况下,向上强制转换是隐式的,向下强制转换应该使用
静态\u强制转换
。您已经在代码中这样做了(WinImp:public Root::BaseDef
类是将
BaseDef
作为
Root
的嵌套类找到的)。换句话说,你实际上自己解决了这个问题。如果你想看得更清楚,我删掉了你文章的一部分。(你的代码可能会模糊你实际看到的内容).@哪一行?您的问题第一段和实际代码正文声明了不同的
类WinImp
(您需要修复)。问题正文(
类WinImp:public BaseDef
)错误;代码中的正文(
类WinImp:public Root::BaseDef
)是的。但是,我建议将
BaseDef
中的那些方法公开,或者至少加以保护。好吧,这确实很奇怪。我链接的示例假设您的所有包含都已正确排列。您能否验证您包含在
WinImp.h
中的
Root.h
(从而
WinImp.cpp
)确实是有你的
类根定义的
Root.h
吗?很简单。暂时在
Root.h
类decl之前插入一个
#error rootinclude
,然后手动编译
WinImp.cpp
,如果它没有中断,那么不知何故你包含了错误的
Root.h
。因为
BaseDef
的命名空间可见性限制为
Root
。您必须限定其命名空间才能访问它。此外,您不应该在
WinImp::foo()
WinImp::bar()前面使用
Root::
definitions。Unrelated:不要将
dynamic\u cast
用于向上播放。仅在向下播放时使用它,并且仅当您不确定播放是否会成功时(因为动态类型未知)实际上,您正在检查强制转换的返回值是否为
!=nullptr
。在已知动态类型的情况下,向上强制转换是隐式的,向下强制转换应该使用
静态\u强制转换
。您已经在代码中这样做了(WinImp:public Root::BaseDef
类是将
BaseDef
作为
Root
的嵌套类找到的)。换句话说,你实际上自己解决了这个问题。如果你想看得更清楚,我删掉了你文章的一部分。(你的代码可能会模糊你实际看到的内容).@哪一行?您的问题第一段和实际代码正文声明了不同的
类WinImp
(您需要修复)。问题正文(
类WinImp:public BaseDef
)错误;代码中的正文(
类WinImp:public Root::BaseDef
)是的。但是,我建议将
BaseDef
中的那些方法公开,或者至少加以保护。好吧,这确实很奇怪。我链接的示例假设您的所有包含都已正确排列。您能否验证您包含在
WinImp.h
中的
Root.h
(从而
WinImp.cpp
)确实是有你的
类根定义的
Root.h
吗?很简单。暂时在
Root.h
类decl之前插入一个
#error rootinclude
,然后手动编译
WinImp.cpp
,如果它没有中断,那么不知何故你包含了错误的
Root.h
@moswald谢谢s、 我不知道为什么我在
Root
中定义了
WinImp
的作用域。但是,我不明白为什么我应该定义
getImp()
WinImp
中。它是
Root
的一个成员函数。哦,天哪,我应该认真编辑我的答案。这是我在流感期间访问的结果。出于某种原因,我认为
getImp
是虚拟的。@moswald谢谢,我不知道为什么我有
W