标头需要彼此

Headers needing each other

本文关键字:      更新时间:2023-10-16

这个问题已经结束,因为它被认为是以下各项的重复:

  1. C++周期性标头依赖项
  2. 头文件之间的循环依赖关系
  3. C++错误:"Line2"尚未声明

然而,另一个问题与我的不同:他们问不同的案例,答案不适用于我的问题。他们的回答建议将函数放入.cpp文件中,并在声明它之前定义类。我不能把函数放在.cpp因为我的类是一个模板,我已经定义了这个类,但它没有用。


我有两个头文件a.hb.h.在它们中定义了两个模板类AB

A的函数需要与B的对象一起工作,反之亦然。由于它们是模板类,我不能将函数放在.cpp文件中,它必须保留在标头中,并且由于包含的顺序,我非常头疼。

解决这个问题的好方法是什么?

目前,我移动函数定义并找到一种以正确顺序包含标头的方法,但这总是变得更加复杂。此外,我不喜欢函数定义远离类声明(例如在其他文件中(。


示例代码:

A.H

#ifndef A_H
#define A_H
#include <iostream>
#include "b.h"
template< typename T > class B;
template< typename T >
class A {
public:
    B<void> *b;
    void f();
    void g();
};
template< typename T > void A<T>::f() {
    std::cout << "A::f" << std::endl;
    b->f();
}
template< typename T > void A<T>::g() {
    std::cout << "A::g" << std::endl;
}
#endif

B.H

#ifndef B_H
#define B_H
#include <iostream>
#include "a.h"
template< typename T > class A;
template< typename T >
class B {
public:
    A<void> *a;
    void f();
    void g();
};
template< typename T > void B<T>::f( ) {
    std::cout << "B::f" << std::endl;
}
template< typename T > void B<T>::g( ) {
    std::cout << "B::g" << std::endl;
    a->g();
}
#endif

主.cpp

#include "a.h"
#include "b.h"
int main( ) {
    A<void> a;
    B<void> b;
    a.b = &b;
    b.a = &a;
    a.f();
    b.g();
    return 0;
}

这不起作用,因为a.h包括b.hb.h不能包含a.h,因此B::g是错误。

对于此示例代码,我可以在main.cppa.h末尾移动B::g,但对于更复杂的程序,这并不容易。

实际上

,您的代码在我的Visual C++上按原样编译。原因是编译器在实际调用函数之前不会查看函数的"内部",即直到main.cpp在您的情况下。

坦率地说,我不确定这是否由标准保证。如果不是,您可以随时将标头拆分为"独立"和"依赖"部分,如下所示:

a_forward.h

#ifndef A_FORWARD_H
#define A_FORWARD_H
template< typename T > class B;
template< typename T >
class A {
public:
    B<T> *b;
    void f();
    void g();
};
#endif

A.H

#ifndef A_H
#define A_H
#include <iostream>
#include "a_forward.h"
#include "b_forward.h"
template< typename T > void A<T>::f() {
    std::cout << "A::f" << std::endl;
    b->f();
}
template< typename T > void A<T>::g() {
    std::cout << "A::g" << std::endl;
}
#endif

b_forward.h

#ifndef B_FORWARD_H
#define B_FORWARD_H
template< typename T > class A;
template< typename T >
class B {
public:
    A<T> *a;
    void f();
    void g();
};
#endif

B.H

#ifndef B_H
#define B_H
#include <iostream>
#include "a_forward.h"
#include "b_forward.h"
template< typename T > void B<T>::f( ) {
    std::cout << "B::f" << std::endl;
}
template< typename T > void B<T>::g( ) {
    std::cout << "B::g" << std::endl;
    a->g();
}
#endif

主.cpp

---||---
相关文章:
  • 没有找到相关文章