【问题标题】:C++ cyclic dependency of classes (Singleton)类的 C++ 循环依赖(单例)
【发布时间】:2020-03-19 19:27:29
【问题描述】:

我在编译具有循环依赖的类时遇到问题,我找不到编译我的代码的方法

主要问题出现在相互依赖的类链中

例如,我有 6 个头文件(类)(A、B、C、D、E、F)

A 包含在 E 中

F、D 包含在 A 中

E包含在F、D中

现在我有一个循环,无法修复它

我简化问题,然后创建一个简单的例子来展示我的确切问题

A.h

#ifndef A_H
#define A_H
#include "B.h"

class A
{
public:
    static A& getInstance()
    {
        static A  instance; 
        return instance;
    }
    int i;
    int sum()
    {
        return i+B::getInstance().j;
    }
private:
    A() {}
};
#endif

B.h
#ifndef B_H
#define B_H
#include "A.h"

class B
{
public:
    static B& getInstance()
    {
        static B  instance; 
        return instance;
    }
    int j;
    int sum()
    {
        return j+A::getInstance().j;
    }
private:
    B() {}
};
#endif
main.cpp

#include "A.h"
#include "B.h"
#include <iostream>
int  main()
{

    A::getInstance().i=1;
    B::getInstance().j=2;
    int t1=A::getInstance().sum();
    int t2=B::getInstance().sum();
    std::cout<<t1<<std::endl;
    std::cout<<t2<<std::endl;
    return 0;
}


g++ main.cpp
In file included from A.h:3:0,
                 from main.cpp:1:
B.h: In member function ‘int B::sum()’:
B.h:17:12: error: ‘A’ has not been declared
   return j+A::getInstance().j;

有什么办法或解决办法解决这个问题吗?

【问题讨论】:

  • 使用前向声明并将实现移动到.cpp 文件中。
  • 前向声明不允许使用类成员。我也不能把实现放到 cpp 文件中,这只是示例,我有大约 1000 行代码的标题,它不仅仅是两个文件,大约 10 个标题。我想找到解决这个概念的解决方案,而不仅仅是这个简单的例子
  • 与前向声明无关,前向声明中只定义了类,不能使用类的成员,表示成员不可用,这是一个类的成员的用法到另一个不仅获得类的对象。
  • @Mohsen,您应该指出问题中的实现约束。

标签: c++ dependencies include singleton cyclic-dependency


【解决方案1】:

如果你因为某种原因不能使用.cpp文件,你可以这样做:

a.h:

#pragma once

class A {
public:
    static A& getInstance();
    int i;
    int sum();

private:
    A();
};

a_impl.h:

#pragma once
#include "a.h"
#include "b.h"

inline A& A::getInstance() {
    static A instance;
    return instance;
}

inline int A::sum() {
    return i + B::getInstance().j;
}

inline A::A() {
}

b.h:

#pragma once

class B {
public:
    static B& getInstance();
    int j;
    int sum();

private:
    B();
};

b_impl.h:

#pragma once
#include "a.h"
#include "b.h"

inline B& B::getInstance() {
    static B instance;
    return instance;
}

inline int B::sum() {
    return j + A::getInstance().i;
}

inline B::B() {
}

然后首先包含声明a.hb.h,然后是实现a_impl.hb_impl.h

#include "a.h"
#include "b.h"
#include "a_impl.h"
#include "b_impl.h"
#include <iostream>

int main() {
    A::getInstance().i = 1;
    B::getInstance().j = 2;
    int t1 = A::getInstance().sum();
    int t2 = B::getInstance().sum();
    std::cout << t1 << std::endl;
    std::cout << t2 << std::endl;
}

现在它将编译。在这个特定的例子中,B(或A)可以在类定义中实现(所以,没有b_impl.h)。为了对称,我将两个类的声明和定义分开。

【讨论】:

    猜你喜欢
    • 2013-02-19
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2013-03-18
    相关资源
    最近更新 更多