【问题标题】:c++ breaking circular dependencie for sort algorithm objectc ++打破排序算法对象的循环依赖
【发布时间】:2012-11-30 03:12:29
【问题描述】:

我有两个班级 A 和 B

A.hpp

#include <vector>
#include <algorithm>
#include "B.hpp"

class A {
public:
  void sortTrans() { std::sort(trans_.begin(), trans_.end(), sortStruct); }
  unsigned int name() { return name_; }
private:
  std::vector<B*> trans_;
  unsigned int name_;
};

B.hpp:

class A;

class B {
  A& source_;
  A& dest_;
  unsigned int choice_;
};

现在我想按选择和名称的值对 trans_ 进行排序,因此我写了

struct sort {
  bool operator()(B* t1, B* t2) {
    if (t1->choice < t2->choice)
        return true;
    if (t1->dest_.name() < t2->dest_.name())
        return true;
    return false;
  }
} sortStruct;

但现在我面临着打破循环依赖的问题。 A的定义在A.hpp中,B的定义在B.hpp中。在 B.hpp 中,我使用 A 的前向减速,A 包括 B.hpp。但是我必须在哪里(或如何)放置 sortStruct,因为它使用 A 和 B 的定义。而且我总是收到错误

Wrong usage of forward declaration A

感谢您的帮助。

【问题讨论】:

  • 您能否向我们展示 A.hpp 和 B.hpp 的全部内容,包括前向声明
  • 当然,我编辑了我的问题
  • 我不确定,但this help ??
  • 您的B 没有您调用的attr1attr2 方法,并且您的sort::operator() 根本没有引用A。你的实际代码是什么样的,编译器抱怨哪一行?
  • 还告诉哪个编译器,哪一行。有帮助!

标签: c++ g++ circular-dependency


【解决方案1】:

您可以将operator() 的声明放在B.hpp 和实现 - 到B.cpp(像往常一样)

// B.hpp
class A;

class B {
  A& source_;
  A& dest_;
};

SortB {
  bool operator()(B* a, B* b); // can be implemented in B.cpp
};

SortB 的实现无需了解class A

// B.cpp
bool SortB::operator()(B* t1, B* t2) {
    if (t1->attr1() < t2->attr1())
        return true;
    if (t1->attr2() < t2->attr2())
        return true;
    return false;
}

A.hpp 中的代码不需要太多改动:

// A.hpp
#include "B.hpp"

class A {
public:
  void sortTrans() { std::sort(trans_.begin(), trans_.end(), SortB()); }
private:
  std::vector<B*> trans_;
  unsigned int attr1_;
  unsigned int attr2_;
};

【讨论】:

    【解决方案2】:

    如果一个类有引用成员,你需要提供构造函数/复制构造函数。你给B提供了吗

    还注意到 t1-&gt;attr2() t2->attr2() 不正确。应该是t1-&gt;attr1_t2-&gt;attr2_

    【讨论】:

      【解决方案3】:

      两个标头都可以使用前向贬值,因为两者都不真正(不需要)依赖于另一个。

      A.hpp

      #ifndef A_HPP
      #define A_HPP
      #include <vector>
      
      class B;
      
      class A {
      public:
        void sortTrans();
        unsigned name();
      private:
        std::vector<B*> trans_;
        unsigned int attr1_;
        unsigned int attr2_;
      };
      #endif
      

      B.hpp

      #ifndef B_HPP
      #define B_HPP_
      class A;
      
      class B {
        A& source_;
        A& dest_;
        unsigned choice_;
      };
      #endif
      

      A.cpp

      #include "A.hpp"
      #include "B.hpp"
      #include <algorithm>
      
      // I can't really define this with your B as given ...
      struct SortB {
          bool operator()(B *x, B *y) {
              if (x->choice_ < y->choice_)
                  return true;
              if (x->dest_.name() < y->dest_.name())
                  return true;
              return false;
          }
       };
      
      void A::sortTrans()
      {
          std::sort(trans_.begin(), trans_.end(), SortB());
      }
      

      请注意,我还没有展示如何访问 B::choice_ 和 B::dest_,因为这是一个设计决策,我没有足够的信息来做出正确的猜测。

      您可以将它们公开(在这种情况下,B 基本上是一个结构),将访问器成员添加到 B,或者将 B.hpp 中的 SortB 前向声明为好友。

      【讨论】:

      • 感谢您的回复。不幸的是,我的问题中有一个错字,消除了依赖。我现在更正了。
      • OK - 你可以在上面的 SortB 中简单地实现它,没有循环依赖。
      • 感谢您的详细回答。完全按预期工作。要访问 B 中的 dest_、source_ 和 choice_,我使用访问器函数。
      【解决方案4】:

      您的排序功能可能不是您想要的。应该是这样的

      if (b1->choice < b2->choice)
          return true;
      if (b1->choice == b2->choice && b1->name < b2->name)
          return true;
      return false;
      

      如果您没有 == 运算符可供选择,则必须使用

      【讨论】:

        猜你喜欢
        • 2020-01-29
        • 2015-10-13
        • 1970-01-01
        • 1970-01-01
        • 2016-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多