Взаимные возвращаемые типы функций-членов (C )

#c #return-value #member-functions #incomplete-type

#c #возвращаемое значение #функции-члены #неполный тип

Вопрос:

Возможно ли в C иметь два класса, давайте назовем их A и B , такие, которые A имеют функцию-член f , которая возвращает объект класса B , и B имеют функцию-член g , которая возвращает объект класса A ?

(Текст ниже просто для того, чтобы показать, что я «сделал свою домашнюю работу».)

Проблема заключается только в том, как написать сигнатуры этих функций, когда та, что находится в первом определенном классе, будет иметь неполный возвращаемый тип. Объявления пересылки здесь не помогают, потому что объекты возвращаются по значению.

Да, я знаю все обходные пути (дружественные глобальные функции, возврат по указателю, …), но я просто хотел бы знать, может ли интерфейс, подобный описанному выше, быть реализован на C . В качестве примера давайте предположим, что я пытаюсь перегрузить operator() для класса, A чтобы возвращать B , и для класса, B чтобы возвращать A . Поскольку я перегружаю операторы, я должен возвращать по значению (ну, если я не хочу динамического распределения, черт возьми :), и () должен быть перегружен как функция-член, поэтому я не могу использовать глобальных друзей.

Ответ №1:

Да, реализуйте определения функций class A после того, как вы объявили class B

 class B;

class A
{
    B f();
};

class B
{
    A g() { A a; return a; }
};

B A::f(){ B b; return b; }
  

Комментарии:

1. Прототипам / объявлениям функций не нужны полностью определенные типы? Полезно знать!

Ответ №2:

Другой возможный способ разорвать цикл зависимостей — использовать шаблонную функцию-член, например:

 struct A {
    template<typename T>  T f() { return T(); }
};

struct B {
    A g() { return A(); }
};

int main() {
    A a;
    B b = a.f<B>();
    A a1 = b.g();
    return 0;
}
  

Это будет работать и для operator (), хотя синтаксис вызова будет довольно уродливым: a.operator()<B>()