C++: два класса ссылаются друг на друга

Итак, чтобы поиграть с дружественными функциями, я решил создать класс Child и класс Mother. Класс Mother имеет элемент данных, который является дочерним. Класс Child создает два метода дружественных функций класса Mother.

Однако когда я компилирую, кажется, что независимо от того, как я обрабатываю включения, я получаю ошибку. Если Child определяется первым, я получаю "Mother is not a class or namespace name" для строки friend void Mother::setChildName(string name); в Child.h. Если Мать определена первой, я получаю «Отсутствует спецификатор типа» для строки Child c; в Mother.h.

Есть ли способ обойти это? Я попытался поставить class Mother; вверху Child.h и class Child; вверху Mother.h, и это, похоже, не помогло.

Или такая циклическая ссылка всегда будет терпеть неудачу?

В Mother.h:

#ifndef MOTHER_H_
#define MOTHER_H_

#include <string>
#include "Child.h"

using namespace std;

class Mother {
public:
    Mother();

    void setChildName(string name);

    string getChildName();

private:
    Child c;
};

#endif

В Mother.cpp:

#include <string>
#include "Mother.h"

using namespace std;

void Mother::setChildName(string name) {
    c.name = name;
}

string Mother::getChildName() {
    return c.name;
}

В Child.h:

#ifndef CHILD_H_
#define CHILD_H_

#include <string>
#include "Mother.h"

using namespace std;

class Child {
public:

private:
    string name;

    friend void Mother::setChildName(string name);
    friend string Mother::getChildName();
};

#endif

person Rstevoa    schedule 06.12.2013    source источник
comment
Пожалуйста, избегайте «использования пространства имен std;» в глобальном масштабе   -  person    schedule 06.12.2013
comment
using namespace std; обычно подходит для файлов .cpp, но в основном никогда не используйте его в файлах заголовков, потому что он загрязняет пространство имен для всех, кто хочет использовать ваш класс (который может включать вас в какой-то момент).   -  person RichardPlunkett    schedule 06.12.2013


Ответы (2)


Эта конкретная проблема не может быть решена без перепроектирования. Мать должна быть определена до Ребенка, а Ребенок должен быть определен до Матери. Самый простой способ — сделать весь класс Матери другом Ребенка. Таким образом, сначала можно определить Child.

Я думаю, что мало практической пользы в том, чтобы подружить отдельные методы с другим классом. Это означало бы, что ваш класс настолько велик, что его обязанности можно разделить на более мелкие классы.

person john    schedule 06.12.2013
comment
Я не уверен, что было бы совершенно справедливо описывать переключение двух операторов дружественных функций для friend class Mother; как редизайн. Уроки в основном те же, и он приближается к тому, к чему стремился. - person RichardPlunkett; 06.12.2013

если мать будет держать указатель на ребенка, вам не нужно будет включать child.h. замедления вперед будет достаточно.

person yosim    schedule 06.12.2013