【问题标题】:Cross access between two classes两个类之间的交叉访问
【发布时间】:2019-09-18 08:51:16
【问题描述】:

我有两个类都必须互相调用公共方法。问题是必须首先定义其中一个类。因此,当我定义一个类时,它必须调用另一个尚未定义的类的方法。 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 下的 clang++)时,我得到了

.\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.hpp

class B;

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

        void changeB();
};

CrossClassAccessB.hpp

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 那样简单)。

【问题讨论】:

  • 你不应该在BA 中的#include "CrossClassAccessA.hpp"A 中也一样吗?
  • 您必须在CrossClassAccessA.cpp 中输入#include "CrossClassAccessB.hpp"(对于其他源文件也是如此)。
  • 这在不重要的地方有帮助,在它所在的地方没有帮助。在 molbdnilo 的回答下查看我的评论。

标签: c++ oop gcc clang


【解决方案1】:

如果你想使用它们,你需要类的定义,所以你需要在两个文件中包含两个头文件。
由于标题不使用除名称之外的“其他”类,因此这不是问题。

【讨论】:

  • 是的,你是对的。当我制作这个例子时,它溜走了。在我的主要项目中,我确实做到了,但我仍然收到此错误invalid use of incomplete type 'class Grid'。在我纠正了那里的简单示例后,它起作用了。
猜你喜欢
  • 2020-09-28
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
相关资源
最近更新 更多