Я решил круговую зависимость. Он был скомпилирован g ++. Уже существующие решения на сайте не включают include в заголовки, а просто добавляют class ...;. Итак, я хочу знать, есть ли проблемы с решением?

Class.h


#ifndef CLASS_A_H
#define CLASS_A_H

class ClassB;

class ClassA {
public:
    ClassB* b;
    int get5();
};

#include "classB.h"

#endif

ClassB.h

#ifndef CLASS_B_H
#define CLASS_B_H

class ClassA;

class ClassB {
public:
    ClassA* a;
    int get7();
};

#include "classA.h"

#endif

Class.cpp

#include "classA.h"

int ClassA::get5() {
    return 5;
}

ClassB.cpp

#include "classB.h"

int ClassB::get7() {
    return 7;
}

Main.cpp

#include <iostream>
#include "classA.h"

int main() {
    ClassA a;
    std::cout << a.get5() << std::endl;
    ClassB b;   
    std::cout << b.get7() << std::endl;
    return 0;
}
c++
-1
TigerTV.ru 27 Апр 2020 в 14:17

2 ответа

Лучший ответ

есть ли проблемы с решением?

Определение B в заголовке classA.h не нужно, и наоборот.

Это ничего не сломает, но может привести к перекомпиляции блоков перевода, включающих один из этих заголовков, когда изменяется любое из определений, даже если эти блоки перевода не зависели от транзитивно включенного определения.

Рекомендуется включать только заголовки, которые необходимо включить.


Другая проблема заключается в том, что в main.cpp вы зависите от определения B, не включая его определение напрямую. Если вы в какой-то момент измените определение A так, чтобы оно больше не зависело от B, и, следовательно, удалите явно ненужное включение, то main.cpp не удастся скомпилировать, так как предполагается, что {{ X3}} определяется включением classA.h.

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

3
eerorika 27 Апр 2020 в 11:35

Это обычное решение, за исключением того, что у вас есть ненужные включения в конце каждого из заголовков. Удалите их, и в main.cpp добавьте classA.h и classB.h.

2
Alex Guteniev 27 Апр 2020 в 11:27