【问题标题】:How can I avoid circular dependency causing error C2039?如何避免循环依赖导致错误 C2039?
【发布时间】:2021-08-02 17:49:11
【问题描述】:

我仍在努力学习 C++,现在已经生成了一个循环依赖项,根据C2039: Class is not a member of Namespace,这可能是导致我遇到 C2039 错误的问题的原因。有人可以帮我剪掉这个圆圈吗?

我有两个模板类,模板类tXmlGeometry<Part> 有一个成员函数,它应该声明模板类tXmlStraightLine 的一个实例。两者都在命名空间nXml 内,但编译器抱怨 tXmlStraightLine 不是 nXml 的成员。 我不得不说我将 tXmlGeometry.h 绑定到 tXmlStraightLine 标头中,但是当我尝试同时将 tXmlStraightLine.h 绑定到 tXmlGeometry 标头时出现错误。我也只是尝试从 tXmlStraightLine 标头中删除 #include nXml/tXmlGeometry 无济于事。

下面是命名空间 nXml 中 tXmlGeometry 模板类的简化代码:

namespace nXml
{
    template<class Part>
    class tXmlGeometry : public tXmlNode<Part> 
    {
    public:
        tXmlGeometry(Part* part);
        ~tXmlGeometry();
        
        void AddStraightLine2D(const pugi::xml_node& node) {};
    };
}
;

以及导致问题的 AddStraightLine2D 方法的实现:

template<class Part>
inline void nXml::tXmlGeometry<Part>::AddStraightLine2D(const pugi::xml_node& this_node)
{
    nXml::tXmlStraightLine<Part> straightline_xml(this);
    //do more stuff
}

这是 tXmlStraightLine 模板类的简化代码:

namespace nXml
{
    template<class Part>
    class tXmlStraightLine : public tXmlSegment2D<Part>
    {
    public:
        tXmlStraightLine(tXmlGeometry<Part>* geo, const int npos);
        ~tXmlStraightLine();
    }
    ;
}
;

有人可以建议我如何避免这种循环依赖吗?

编辑:我更正了成员函数命名中的一个错误。

【问题讨论】:

  • 将方法的定义移到tXmlStrightLine的定义之后。它不是真正的“圆形”
  • 我不确定我是否理解将方法的定义移到 tXmlStraightLine 的定义之后的意思。你的意思是我应该将方法移到类 tXmlStraightLine 后面还是你的意思是我应该在方法之前和之外声明 straightline_xml?
  • 我的意思是:godbolt.org/z/PGhvG7nd1(我只需要修正一些错别字并添加缺少模板的虚拟定义,还有AddCircle2D vs AddStraightLine2D,你有AddStraightLine2D的定义当我认为您只想在第一个 sn-p 中声明它时)
  • 非常抱歉,我犯了一个错误。为了减少代码,我删除了错误的成员函数。我将编辑原帖

标签: c++ dependencies


【解决方案1】:

由于它们都是模板类,我会考虑将它们放在同一个标​​题中。 为了避免依赖性问题,您可以将声明和定义分开。像这样的:

namespace nXml
{
    // tXmlGeometry<Part> declaration
    template<class Part>
    class tXmlGeometry : public tXmlNode<Part> 
    {
    public:
        tXmlGeometry(Part* part);
        ~tXmlGeometry();
        
        inline void AddStraightLine2D(const pugi::xml_node& this_node);
    };

    // tXmlStraightLine  declaration
    template<class Part>
    class tXmlStraightLine : public tXmlSegment2D<Part>
    {
    public:
        tXmlStraightLine(tXmlGeometry<Part>* geo, const int npos);
        ~tXmlStraightLine();
    };

    // tXmlGeometry<Part> definitions
    template<class Part>
    inline void nXml::tXmlGeometry<Part>::AddStraightLine2D(const pugi::xml_node& this_node)
    {
        nXml::tXmlStraightLine<Part> straightline_xml(this);
        //do more stuff
    }
}
;

【讨论】:

  • 谢谢!理想情况下,我可以避免将 tXmlStraightLine 放在同一个文件中,因为我还有其他需要开发的类和进一步的东西,我也需要复制到那里(为简单起见,它不在示例代码中)。每个都有自己的成员函数和实现。该文件将难以阅读。
  • @ManyQuestions 所以有两种方法可以将其拆分为更多文件:创建一个包含定义的文件并将其包含在 .h 文件的底部 - 这样,在预处理之后,您将把所有内容都留在一个文件中。湾。显式实例化 - 在标题中添加行:template class tXmlStraightLine&lt;Part&gt;;。这告诉编译器tXmlStraightLine 将被Part 实例化。然后,您可以创建一个包含定义的 .cpp 文件并将其添加到您的项目中。
猜你喜欢
  • 2013-02-06
  • 1970-01-01
  • 2012-02-15
  • 2013-04-02
  • 2013-03-18
  • 2012-08-10
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多