静态成员与静态全局

时间:2013-07-29 15:55:19

标签: c++ linker

我已经读过,全局变量和静态全局变量之间的区别在于全局变量可以通过extern在另一个实现文件中引用,而静态全局变量仅局限于该实现文件。有关详细信息,请参阅这两个问题:[12]。

根据我的理解,这意味着以下foo()bar()应该相同地链接。这两个函数只能由MyClass使用。

//MyClass.h
Class MyClass{
private:
  static void foo();
};

//MyClass.cpp
void MyClass::foo(){}
static void bar(){}

我可以看到foo()的声明更常见,因为它让头文件更完整地布局整个类(即使你不能/不应该使用私有的东西),但是很糟糕练习声明像bar()这样的函数(隐藏在头文件中)?

对于上下文,我为windows消息定义WNDPROC,需要静态才能工作,但这是一个相当丑陋的声明,我不确定是否应该将它完全隐藏在实现文件中或者去提前并在头文件中声明它。

1 个答案:

答案 0 :(得分:8)

static是一个非常可怕的关键字,因为它具有许多不同的含义,具体取决于上下文。静态变量和静态函数完全不同,类中的静态函数和静态自由函数完全不同。

类中的静态函数意味着可以在没有类实例的情况下调用该函数,但它不能访问该类的非静态成员。它有点像常规函数,只是为了整洁而附在课堂上。

静态自由函数具有内部链接,因此在源文件之外无法看到它,并且其名称可以在其他源文件中重用。

静态类函数没有内部链接。所有类功能都有外部链接。无论类函数是否为静态,都可以在头文件和源文件之间拆分类函数。

我建议您阅读一些教程/书籍,以便更清楚地了解静态的许多不同用法。当你在一个你以前没见过的地方看到静电时,什么都不做!

如果您想要隐藏在源文件中的自由函数,则可以将其声明为静态。或者,您可以将其放在未命名的命名空间中。

// cpp file only
namespace
{
    void hiddenfunc() {..}
}

这类似于

static void hiddenfunc();

它可以以相同的方式调用(就像“hiddenfunc()”)。未命名的命名空间(我知道一个奇怪的名称)的一个优点是,您还可以放置您希望在该源文件中可见的类和其他定义。只需确保在命名空间{..}区域中定义函数体。不要在头文件中放入未命名的命名空间。