4

我正在做 C++ 编码。

从文件 f2.cpp 中,我需要调用在 f1.cpp 中定义但未在 f1.h 中删除的函数 f1()。

我不能通过在 f2.cpp 中包含 f1.h 来做到这一点。

我不想定义另一个做同样事情的函数,它是重复的。

如何解决这个问题呢 ?

谢谢

更新

阅读解决方案后,我将在 f1.h 中添加 f1() 的清除。

在 f1.h 中,它有

namespace name1{
   namespace name2{
      class class1{};
      class class2{};
   }
}

f1() 只是一个实用函数,不涉及 clas1 和 class2 的成员。

目前,f1() 是在 f1.cpp 中的命名空间(没有名称)中定义的。

namespace{
  f1(){

  }
}

但是,在 f1.h 中,它有一个命名空间定义 name1 和 name2。

我应该把 f1() 清除在 f1.h 哪里?

现在,我将 f1() 放入 f1.h 中的 name1::name2 并将 f1.h 包含在 f2.cpp 中,我得到链接错误:来自 f2() 的 undefiend name1::name2::f1()。

更新 如果我将 f1() 的声明放在任何命名空间之外的 f1.h 中,并且还包括来自 f2.cpp 的 f1.h,我得到链接错误:f2() 中 f1() 的未定义符号,为什么?

任何帮助将不胜感激 !

4

4 回答 4

2

在 f2.cpp 中将函数声明为 extern

//f2.cpp    
extern void f();   //function declared but defined elsewhere

int main() {    
    f();
}

//f1.cpp
void f() {    
   //function declaration    
}

g++ f2.cpp f1.cpp ,可以正常工作。

话虽如此,您也可以执行 f2.cpp 的#include,这会起作用,但绝对是个坏主意,因为如果将两个文件一起编译,则会出现多个定义错误。如果在您的控制下,正确的做法是使用带有函数声明的 f1.h。

更新:对于使用命名空间的修改问题,通过在 f() 周围使用未命名命名空间,您明确告诉编译器将函数的可见性限制为该文件。您可以更改为命名空间,然后在头文件中引用其声明

于 2013-06-14T22:57:15.277 回答
1

您要使用的实用程序函数位于匿名命名空间中,其概念类似于static. 它使该函数仅对该源文件可见。

如果您不想将函数移出f1.cpp,则需要以某种方式公开实用函数的接口。一种方法是将函数移动到具有名称的新名称空间中,例如f1_util。然后,您可以在 中声明实用程序函数的存在f1.h

// f1.cpp
namespace {
    // move f1() out of this
}
namespace f1_util {
  void f1(){
    //...
  }
}
using namespace f1_util;
//... rest of f1.cpp

// f1.h
namespace f1_util {
    void f1();
}
//... rest of f1.h

最好将实用程序函数移动到一个新的源文件中,例如 ,util.cpp并确保它不在匿名命名空间中。然后定义一个util.h声明它的。然后两者都有f1.cppf2.cpp包括util.h.

于 2013-06-14T22:52:31.030 回答
0

将声明放入f1()in f2.cpp。声明的位置对编译器无关紧要,它只是一种编程约定,声明和定义放在相应的头文件和源文件中。不过,这是一个很好的做法:如果您在 中更改函数的标头,则f1.cpp只需在 中更新该声明f1.h,您不必在.cpp调用该函数的所有其他文件中查找它。这就是我们首先使用头文件来实现模块化的原因。

于 2013-06-14T22:47:28.083 回答
-1

为什么不直接包含 f1.cpp 或在 f1.h 中声明函数?

于 2013-06-14T22:27:58.077 回答