【问题标题】:C++ inheritance problem with namespaces命名空间的 C++ 继承问题
【发布时间】:2010-11-12 13:48:06
【问题描述】:

好的,我一直在寻找,但我无法找到为什么这不起作用的原因:

基类(misc/interface/handler.h)

#ifndef __t__MISC_VIRTUAL_HANDLER_H
#define __t__MISC_VIRTUAL_HANDLER_H
#pragma message("Starting with 'handler.h'")

namespace t {
    namespace misc {
        namespace interface {
            class Handler {
                public:
                    Handler();
                    virtual ~Handler();

                    virtual int setup() = 0;
                    virtual int teardown() = 0;
                    virtual int update() = 0;
                protected:
                private:
            };
        }
    }
}

#pragma message("Ending with 'handler.h'")
#endif // __t__MISC_VIRTUAL_HANDLER_H

派生类(graphics/handler.h):

#ifndef __t_GRAPHICS_HANDLER_H
#define __t_GRAPHICS_HANDLER_H

#include "../misc/interface/handler.h"

namespace t {
    namespace graphics {
        class Handler: public t::misc::interface::Handler {
            public:
                Handler();
                virtual ~Handler();

                int getResolutionX() { return m_resolutionX; }
                int getResolutionY() { return m_resolutionY; }
                bool getFullscreen() { return m_isFullscreen; }

            protected:
            private:
                unsigned int m_resolutionX, m_resolutionY;
                bool m_isFullscreen;

        }; // class Handler
    } // namespace graphics
} // namespace t
#endif // __t_GRAPHICS_HANDLER_H

...这似乎是微不足道的。

派生类实现(graphics/handler.cpp):

#include "handler.h"

t::graphics::Handler::Handler(): t::misc::interface::Handler() {

}

t::graphics::Handler::~Handler() {
}

... 这也应该是微不足道的,但会产生错误:

src\graphics\handler.cpp|5|undefined reference to `t::misc::interface::Handler::Handler()'

我正在使用带有代码块的 MinGW 以及 CB 使用的任何标准设置,我尝试使用测试类构建相同的情况,并且在相同的环境和带有 vanilla g++ 的 Linux 中都按预期工作。

【问题讨论】:

  • 尝试删除命名空间并查看问题是否可以重现。将文件放入同一目录并执行相同操作:如果未打印 pragma,则该文件未包含,或者已定义包含保护。时期。始终努力生成重现问题的最小代码。
  • 同意@Konrad。事实上,您会发现只需为 SO 准备问题,您就会多次解决问题。

标签: c++ inheritance namespaces virtual


【解决方案1】:

我在你的代码中看不到任何t::misc::interface::Handler::Handler() 的实现——它会被继承类的构造函数调用,所以它需要一个实现。链接器找不到它,所以它会报错。

只是改变:

Handler();
virtual ~Handler();

在抽象类中:

Handler() {}
virtual ~Handler() {}

你准备好了。

【讨论】:

    【解决方案2】:

    顺便说一句,以两个下划线开头的标识符在 C++ 中是非法的(因为它们是为编译器保留的)。在实践中,它们不应该在预处理器中成为问题,但最好在安全方面犯错:干脆不要使用它们。

    【讨论】:

    • 已修复。 (但编译器不应该抱怨吗?)
    • @JDW:不。基本上编译器只是首选。它可以定义该类别中的任何名称,但如果它不能,那么实际上没有什么可以阻止您自己定义名称。但如果最终发生冲突,那是你的错,因为你使用了保留名称。他们不是被禁止的,只是危险的。 (完整的保留名称集是:任何名称包含双下划线,任何以下划线开头后跟大写字母的名称,以及在命名空间范围内以下划线开头的任何名称(即不在内部一个函数或类)
    • 把它想象成跑到高速公路上。没有人阻止你这样做,只要你注意(并且很幸运)你就可以逃脱它,但是有可能被卡车撞到,如果你这样做了,那真的是你自己的错。因此,远离会更安全。
    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 2017-09-27
    • 2013-03-10
    • 1970-01-01
    • 2020-03-20
    • 2013-08-13
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多