g ++ — c ++ нарушение круговой зависимости для объекта алгоритма сортировки

у меня есть два класса 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

Спасибо за помощь.

-1

Решение

Оба заголовка могут использовать прямое отклонение, поскольку ни один из них (не должен) зависеть от другого.

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или заранее объявить SortB в B.hpp как друг.

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_;
};
0

если класс имеет ссылочный член, вам нужно предоставить конструктор / конструктор копирования. Вы предоставили это для B

Также заметил, что t1->attr2() < t2->attr2() не правильно Так должно быть t1->attr1_ а также t2->attr2_

0

Ваша функция сортировки, вероятно, не соответствует вашим ожиданиям. Это должно быть что-то вроде

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

Если у вас нет оператора == для выбора, вы должны использовать < оператор перевернут и отрицается для достижения той же функциональности

0