加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C调用方法时的前向声明问题

发布时间:2020-12-16 10:15:21 所属栏目:百科 来源:网络整理
导读:我有一个问题,我认为这与前向声明有关,但也许不是. 这是相关代码: 啊 #ifndef A_H_#define A_H_#include "B.h"class A{ private: B b; public: A() : b(*this) {} void bar() {}};#endif /*A_H_*/ B.h #ifndef B_H_#define B_H_#include "A.h"class A;class
我有一个问题,我认为这与前向声明有关,但也许不是.

这是相关代码:

#ifndef A_H_
#define A_H_

#include "B.h"

class A
{
    private:
        B b;

    public:
        A() : b(*this) {}

        void bar() {}
};

#endif /*A_H_*/

B.h

#ifndef B_H_
#define B_H_

#include "A.h"

class A;

class B
{
    private:
        A& a;

    public:
        B(A& a) : a(a) {}

        void foo() { /*a.bar();*/ } //doesn't compile
};

#endif /*B_H_*/

main.cpp中

#include "A.h"

int main()
{
    A a;

    return 0;
}

问题似乎是调用A :: bar().程序成功编译,直到我尝试调用此方法,此时我得到两个错误:

error: invalid use of incomplete type ‘struct A’

error: forward declaration of ‘struct A’

我认为这是因为A :: bar()尚未定义或声明,因为两个标题相互引用.但是,我转发申报的A级,我不知道还需要做什么.我是C的新手,所以请原谅我.我无法在网上找到这个问题的答案.一如既往,提前谢谢!

解决方法

你有一个循环引用,所以你需要分开B.h.尝试类似的东西:

B.h:

#ifndef B_H_
#define B_H_

// don't include A.h here!

class A;

class B
{
   private:
      A& a;

   public:
      B(A& a) : a(a) {}

      void foo();
};

#endif /*B_H_*/

B.cpp:

#include "B.h"
#include "A.h"

void B::foo() { a.bar(); } // now you're ok

编辑:解释为什么需要将其拆分为两个文件:

B类包含对A的引用,可以是所谓的不完全类型.你不能调用任何函数,因为编译器还不知道A是什么 – 它只知道它是某种类.一旦你包含A.h(在.cpp文件中),那么A就是一个完整的类型,你可以用它做任何你喜欢的事情.

您不能将整个事件保存在一个头文件中,因为您将获得循环引用.你阻止了包含守卫的无限循环,但是你得到了一些你不想要的东西.看看编译器在编译main.cpp时最终会遇到什么,就像之前一样:

// #include "A.h" ==>
#define A_H_

// #include "B.h" ==>
#define B_H_

// #include "A.h" ==> nothing happens! (since A_H_ is already defined)

class A;

class B {
private:
    A& a;

public:
    B(A& a) : a(a) {}

    void foo() { a.bar(); } // <-- what the heck is A here?
                            //     it's not defined until below
};

class A {
private:
   B b;

public:
   A() : b(*this) {}

   void bar() {}
};

int main() {
    A a;
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读