我刚开始学习C ++。有人可以解释下面的C ++函数原型之间的区别吗?
void f(int n);
extern void f(int n);
static void f(int n);
答案 0 :(得分:11)
void和extern void版本是相同的。它们表明该函数具有外部链接(即,可以预期函数的定义来自某些其他C或C ++文件)。 Static表示该函数具有内部链接,并且仅存在于当前C ++文件中。
您几乎从未看到这些说明符应用于函数,因为99.9%的时间您希望使用默认的extern
行为。
您可能会在全局变量上看到static
或extern
存储说明符,这通常用于减少与同一项目中其他文件的名称冲突。这是C的延续;如果您使用的是C ++,则应使用匿名命名空间而不是static
来完成此类操作。
答案 1 :(得分:4)
这更像是C语言问题,而不是C ++问题,但是:
void f(int n);
声明一个带有单个整数参数的函数f。
extern void f(int n);
声明一个函数f,它接受一个整数参数但存在于其他文件中。编译器将相信您已在某处实现了该功能。如果链接器找不到它,您将收到链接器错误。
static void f(int n);
声明一个带有单个整数参数的函数f。 static关键字使这很有趣。如果这是在.cpp文件中,则该功能仅对该文件可见。如果它位于.h文件中,则包含该标头的每个.cpp文件都将创建自己的该函数副本,该副本只能由该实现文件访问。
答案 2 :(得分:3)
前两个是相同的。第三个提供f
内部链接,这意味着不同的源文件可能使用名称f
作为不同的东西。
不应使用第三个例子中static
的使用。而是使用匿名命名空间:
namespace { // anonymous
void f(int n);
}
答案 3 :(得分:0)
到目前为止,这两个答案都不赞成使用静态函数。为什么?是什么让
命名空间{
void f(int n);
}
优于
static void f(int n);
?这并不简单,理解起来并不容易......
答案 4 :(得分:0)
匿名命名空间是一种更通用,更清晰的解决方案,您可以在其中包含函数,变量和类。并且static
过于过载,在某些情况下意味着内部联系,在其他静态生命周期中
但是匿名命名空间有一个缺点。由于外部链接,对象/库文件的导出部分将膨胀,所有那些长<unique namespace name>::<function>
个名称都不会是静态的。