两个依赖结构的内联方法?

Inline methods of two dependant structures?

我想内联我的两个结构。但是他们有彼此的指针。喜欢下面的代码:

A.h

#ifndef A_H
#define A_H

#include "b.h"

struct A
{
    B* b;
    int value;

    A();
    void Inc();
};

#endif // A_H

A.cpp

#include "a.h"

A::A()
{
    b = new B(this);
}

void A::Inc()
{
    b->value++;
}

B.h

#ifndef B_H
#define B_H

struct A;

struct B
{    
    A* a;
    int value;

    B(A* a);
    void Inc();
};

#endif // B_H

B.cpp

#include "b.h"
#include "a.h"

B::B(A *a)
{
    this->a = a;
}

void B::Inc()
{
    a->value++;
}

main.cpp

#include <iostream>
#include <a.h>

using namespace std;

int main()
{
    A a;
    a.value = 0;
    a.b->value = 0;
    a.Inc();
    a.b->Inc();
    cout << a.value << endl;
    cout << a.b->value << endl;
    return 0;
}

我不能在任何地方使用关键字 inline 因为它给我错误 undefined reference to methods.

基于here,我可以在头文件中定义我的方法,但这会迫使我在文件b.h 中使用#include <a.h>。但由于重复包含,这会给我另一个错误。

现在如何内联这两个 Inc 方法?

不可能在 struct 定义的主体中内联两个相互依赖的 struct 的所有成员函数。可以通过在 struct 定义主体之外定义函数并显式使用 inline 关键字来内联所有成员函数。但是,如果你使用两个.h文件来定义struct/classs,它就变得凌乱了。

这里有一些实现成员函数的选项。

选项 1

仅在 .h 文件中使用前向声明。实现.cpp 文件中的所有函数。 None 个成员函数是内联的。

选项 2

B.h 中使用 A 的前向声明,但在 A 中使用 B 的完整定义。 在这种情况下,A的所有成员函数都可以被内联,但B的成员函数不能被内联。它们将需要在 .cpp 文件中实现。

选项 3

选项 2

中调换 AB 的角色

A.h 中使用 B 的前向声明,但在 B 中使用 A 的完整定义。 在这种情况下,B的所有成员函数都可以被内联,但A的成员函数不能被内联。它们将需要在 .cpp 文件中实现。

a.hb.h 保持不变,a.cppb.cpp 合并为 ab_inl.hpp 包含带有 [=17= 的方法和构造函数] decorator** (或者你可以让构造函数在它们各自的 .cpp 文件中)和 main.cpp (或任何其他需要它的文件)包括 ab_inl.hpp.


** 因为编译器可以随意忽略 inline 限定符,所以我更喜欢术语 "decorator"


下面的所有内容 + a.h + b.h 编译得很好:

文件ab_inl.hpp:

#ifndef _AB_INL
#define _AB_INL

#include "a.h"

// included by a.h anyway
// #include "b.h"

inline A::A() : b(0), value(0)
{
    b = new B(this);
}

inline void A::Inc()
{
    b->value++;
}

inline B::B(A *a) : a(0), value(0)
{
    this->a = a;
}

inline void B::Inc()
{
    a->value++;
}

#endif // _AB_INL

文件main.cpp

#include "ab_inl.hpp"


int main()
{
    using std::cout;
    using std::endl;

    A a;
    a.value = 0;
    a.b->value = 0;
    a.Inc();
    a.b->Inc();
    cout << a.value << endl;
    cout << a.b->value << endl;
    return 0;
}