Доступ к кресту между двумя классами

У меня есть два класса, которые оба должны вызвать открытые методы друг на друге. Проблема в том, что один из этих классов должен быть сначала определен. Поэтому, когда я определяю одного класса, он должен вызывать методы из другого класса, который еще не определен. Вперед объявлении класса B также не поможет. Таким образом компилятор знает только, что класс B существует, но не входящих в нее членов. Но компилятор должен знать их, когда changeB() определяется.

Вот упрощенный пример

#include <iostream>

class B;

class A {
    public:
        B* b;
        int data = 0;

        void changeB(){
            b->data = 5;
        }
};

class B {
    public:
        A* a;
        int data = 0;

        void changeA(){
            a->data = 5;
        }
};

int main(int argc, char const *argv[]) {
    A a;
    B b;

    a.b = &b;
    b.a = &a;

    a.changeB();
    b.changeA();

    std::cout << "a.data: " << a.data << std::endl;
    std::cout << "b.data: " << b.data << std::endl;

    return 0;
}

Когда я скомпилировать этот (лязг++ под Windows 10) я получаю

.\CrossClassAccess.cpp:12:14: error: member access into incomplete type 'B'
            b->data = 5;
             ^
.\CrossClassAccess.cpp:3:7: note: forward declaration of 'B'
class B;
      ^
1 error generated.

После того как я сделал этот простой пример, я подумал, что, возможно, помогло бы, если бы я сначала объявить обоих классов, а затем определить методы. До определенного момента, он помог и показал ожидаемое решение.

#include <iostream>

class B;

class A {
    public:
        B* b;
        int data = 0;

        void changeB();
};

class B {
    public:
        A* a;
        int data = 0;

        void changeA();
};

void A::changeB(){
    b->data = 5;
}

void B::changeA(){
    a->data = 5;
}

// main() is still the same

Но я хотел сделать это ближе к реальности, чтобы понять, почему это не работает в моей реальной проекта. так что я разделить файл в основной файл, два файла cpp и две жатки. После этого он больше не работал.

CrossClassAccessMain.cpp

#include <iostream>
#include "CrossClassAccessA.hpp"
#include "CrossClassAccessB.hpp"

int main(int argc, char const *argv[]) {
    A a;
    B b;

    a.b = &b;
    b.a = &a;

    a.changeB();
    b.changeA();

    std::cout << "a.data: " << a.data << std::endl;
    std::cout << "b.data: " << b.data << std::endl;

    return 0;
}

CrossClassAccessA.ГЭС

class B;

class A {
    public:
        B* b;
        int data = 0;

        void changeB();
};

CrossClassAccessB.ГЭС

class A;

class B {
    public:
        A* a;
        int data = 0;

        void changeA();
};

CrossClassAccessA.cpp

#include "CrossClassAccessA.hpp"

void A::changeB(){
    b->data = 5;
}

CrossClassAccessB.cpp

#include "CrossClassAccessB.hpp"

void B::changeA(){
    a->data = 5;
}

Когда я компиляции этого, я получаю снова эта ошибка

.\CrossClassAccessA.cpp:4:6: error: member access into incomplete type 'B'
    b->data = 5;
     ^
./CrossClassAccessA.hpp:1:7: note: forward declaration of 'B'
class B;
      ^
1 error generated.
.\CrossClassAccessB.cpp:4:6: error: member access into incomplete type 'A'
    a->data = 5;
     ^
./CrossClassAccessB.hpp:1:7: note: forward declaration of 'A'
class A;
      ^
1 error generated.

Команду я использую для компиляции

clang++ .\CrossClassAccessMain.cpp .\CrossClassAccessA.cpp .\CrossClassAccessB.cpp

Когда я изменить порядок CrossClassAccessA и CrossClassAccessB я получаю ту же ошибку, только с перевернутым заказа.
Для меня это выглядит так, что один cpp файл компилируется перед другой заголовочный файл был проанализирован.
Так как я могу довести процесс компиляции в порядок мой пример, который работает, даже если я разделить мой код в разные файлы?
Для этого примера я использую Clang++. В моем основном проекте я использую Arduino и я собираю его через командную строку с arduino_debugger.exe. Я думаю, что в бэкэнде это с помощью avr-gcc компилятором. Я не уверен, если я могу передать флаги компилятора arduino_debugger.exe. Если нет (я уверен, что наоборот) я тоже могу скомпилировать его непосредственно с avr-gcc и (но это будет не так просто, как с arduino_debugger.exe).

0
2019-09-18 10:51:16
источник
0 ответов

Посмотрите другие вопросы по меткам