Имеется два класса, один из которых имеет методы, которые дружественны другому классу, но из-за того, что первый имеет в себе объект второго я не знаю как правильно разместить их в header. Если вписывать сначала Koords а потом Complexity, то компилятор не видит дружественные функции, а если наоборот (как ниже), то ошибкой подсвечивается объявление объекта типа Koords в классе Complexity. Что делать?
class Koords;
class Complexity {
private:
Koords sizes_;//сдесь выдает ошибку
unsigned short mines_;
public:
explicit Complexity(int = EASILY);
auto getY() const;
auto getX() const;
auto getM() const;
Koords return_sizes() const;
};
class Koords {
private:
unsigned short y_;
unsigned short x_;
public:
Koords(const int y = 0, const int x = 0);
auto getY() const;
auto getX() const;
friend auto Complexity::getY() const;
friend auto Complexity::getX() const;
};
Объявить другом весь класс Complexity
class Koords {
...
friend class Complexity;
...
};
Тогда Complexity может быть объявлен где угодно или его может вообще не быть. А вообще незачем тут напрямую за координатами лазить, т.к. если getX/Y не виртуальное, е тело вырождается до return x_;, то компилятор тебе так наоптимизирует, что ничем от прямого доступа к x,y отличатся не будет.
class Koords;
Компилятор не имеет ни какого предчувствия, сколько памяти нужно определить для класса Koords, и так строка
Koords sizes_;
натурально выдает ошибку, так как переменная Koords коммандой
class Koords;
не определена, она только декларирована.
Обычной подход - использование указателя на класс (его длину компилятор знает, так как длина всех указателей одинаковая, обычно 4 или 8 байтов в зависимости от операционной системы и компилятора), а не самого класса:
Koords *sizes_;
Дружественность к методам ещё не определённого класса не будет работать. Объявление класса с ещё не определёнными типами не получится. Так-как класс Complexity полностью зависит от реализации Koords, дружественность класса Koords к методам дочернего класса Complexity это нереализуемое счастье. Единственным выходом из сложившейся ситуации вижу только статическое объявление метода, дружественного с обоими классами. Причём тип auto придётся переделать на что-то конкретное (unsigned short).
class Complexity;
class Koords {
private:
unsigned short y_;
unsigned short x_;
public:
Koords(const int y = 0, const int x = 0);
unsigned short getY() const;
unsigned short getX() const;
friend unsigned short getY(Complexity const & ) ;
friend unsigned short getX(Complexity const & ) ;
};
class Complexity {
private:
Koords sizes_;
unsigned short mines_;
public:
explicit Complexity(int = EASILY);
friend unsigned short getY(Complexity const & ) ;
friend unsigned short getX(Complexity const & ) ;
auto getM() const;
Koords return_sizes() const;
};
unsigned short getY(Complexity const & ) ;
unsigned short getX(Complexity const & ) ;
Сборка персонального компьютера от Artline: умный выбор для современных пользователей