C ++有没有办法解决循环依赖?

时间:2015-02-12 13:30:15

标签: c++ circular-dependency

现在我知道在C ++中,必须先声明所有内容才能使用它。但是,如果我有两个相互引用的函数呢? 例如:

void func1() {
  func2();
}

void func2() {
  func1();
}

完全不可能这样做吗?

6 个答案:

答案 0 :(得分:3)

前瞻性声明正是您想要的:

void func2(); // forward declare func2

void func1() {
  func2();
}

void func2() {
  func1();
}

第一个void func2();被称为前向声明。您保证最终会根据此原型定义它。

答案 1 :(得分:3)

您需要转发声明func2()才能在func1()中使用它:

void func2();

void func1() {
  func2();
}

void func2() {
  func1();
}

现在,func1()引用func2()func2()已被宣布,func2()引用func1()func1()将被宣布。

但是,调用两个函数中的任何一个都会导致无限循环,这将导致堆栈溢出。

答案 2 :(得分:0)

您可以简单地将一个函数放在另一个函数中,然后表示为类的(通常为static)成员函数,或者表示为lambda。

这假设来自其他地方的顶级调用始终是其中一个函数。

顶层调用代码可用的两种函数的另一种可能性是将两个函数都放在一个类的(最自然static)成员中,它们可以在内联定义。

但我认为使用前瞻声明会更加干净。

没有任何理由可以避免它,所以像上面提到的那样的解决方法只会让其他程序员浪费一些时间来摸不着头脑 - 这是 >


修正案:类范围方法的例子:

struct Recursive
{
    static void func1() { if( some_condition ) { func2(); } }
    static void func2() { if( some_condition ) { func1(); } }
};

嵌套函数方法示例:

void func1()
{
    const auto func2 = []{ if( some_condition ){ func1(); } }
    if( some_condition ) { func2(); }
}

答案 3 :(得分:0)

如果没有某种前瞻性声明,那段代码是不可能的?是。想一想,当编译器到达这里时:

void func1() {
  func2();
}

他之前从未见过func2,因此无法编译它。

大多数人创建一个包含函数声明的.h文件,以便您可以避免这种类型的事情。例如,

foo.h

void func1();
void func2();

foo.c

#include "foo.h"

void func1() {
  func2();
}

void func2() {
  func1();
}

答案 4 :(得分:0)

成员函数当然可以。例如:

class A {
  void func1() {
    func2();
  }
  void func2() {
    func1();
  }
};

如果您需要两个课程来了解彼此,但这样做可以回答您的问题,那么问题会更多吗?

编辑:在定义之前不需要成员函数声明。

答案 5 :(得分:0)

你应该接受其他一个答案,因为这就是C ++语言的工作方式,并且没有任何关系,如果你担心写很多前锋是一件痛苦的事情,你应该注意到几个框架已经提供了标题为了向前宣布东西,以便用户也没有。

这是为了方便,因为有很多东西是向前声明的,或者有些东西需要正确声明(在示例模板,别名中,我偶尔会看到一些宏诡计)。

通常,您必须将声明和定义放在不同的文件中,以避免在可能的情况下重新编译,并且通常可以使项目更加清晰和易于管理。

<强> Functions.hpp

void func();
void func2();

<强> Functions.cpp

#include "Functions.hpp"

void func(){
    func2();
}

void func2(){
    func();
}

用户代码: 的的main.cpp

#include "Functions.hpp"

int main(){
    func();
    return 0;
}

另请注意,您对“声明”和“转发声明”存在一些疑惑。

实际上,当您在代码中添加功能签名时,您声明

int function3(); // function declared

转发声明是关于告诉某个类存在而不再告诉其签名:

class myclass;  //forward declaration

//possible declarations using "myclass" forward declaration
int function4(myclass & ref);
int function5(myclass * ref);

前向声明用于通过将不需要的详细信息移动到实现(.cpp)文件来简化标头并减少编译时间(在某些情况下很多)。