我想知道人们是否可以对“静态”的使用有所了解。我从未遇到过明确声明变量或方法为静态的问题。我了解到,在将某些内容声明为“静态”时,它会塞入程序的数据段(类似于全局变量),因此可以在程序运行时访问该变量。如果是这种情况,为什么不只将静态变量设为全局变量。哎呀,为什么不使用新的或malloc将此变量扔到堆上呢,这两种方法都确保变量在整个程序运行期间都对您可用。
最佳答案
static
在C中具有多种含义,而C++堆甚至更多。
在文件作用域声明(我认为问题是关于什么)中,静态控制标识符的可见性。
让我们搁置C++并使用C概念。
名称对象或函数具有链接的文件作用域标识符。链接可以是外部的(程序范围的)或内部的(一个翻译单元内)。static
指定内部链接。
这很重要,因为如果带有内部链接的名称以多个单位出现,则这些出现无关。一个模块可以具有静态foo
函数,而同一程序中的另一个模块可以具有不同的foo
函数。它们都存在,并且可以通过名称foo
从各自的单元中访问。
对于外部链接,这是不可能的:必须有一个foo
。malloc
创建一个对象,该对象可能在程序中的任何地方都可用,只要它没有被释放,而是具有不同的意义。如果有其指针,则该对象可用。指针是一种“运行时名称”:一种访问对象的访问键。如果您知道对象或函数的名称(在编译时)并且相对于您尝试从其访问的位置,该对象或函数具有正确的链接类型,则链接可使该对象或函数可用。
在一个动态的操作系统中,有多个程序生效并终止,其静态数据和功能(无论它们具有外部还是内部链接)的存储实际上是动态分配的。加载程序的系统例程必须执行类似于malloc
的操作才能为程序的所有固定区域获取内存。
有时,C程序甚至对通过全局指针全局引用的“单个”对象也使用malloc
。这些对象的行为就像事实上的静态变量一样,因为它们的生存期几乎是整个程序的生存期,并且可以通过按名称访问的指针进行访问。如果对象具有直到运行时才知道的属性(例如大小),或者如果对象的初始化很昂贵并且并不总是需要它们(仅在程序中发生某些情况时),则此选项很有用。
关于static
和extern
的补充类事实:
extern
确保实际上省略了初始化程序的对象的声明。如果没有extern
,则它是一个暂定定义,但是如果存在初始化器,则它是一个定义。 extern
并不意味着“此声明具有外部链接”。 extern
声明继承了先前具有相同名称的声明的链接。 extern
表示“此名称(正在引入此范围,是指具有外部链接的外部定义”)。该链接从名称的先前文件作用域声明继承(如果存在),否则是外部的。 static
不是控制链接,而是控制存储持续时间。每次进入该块时,不会实例化static
对象;它的一个副本存在,并且可以在程序启动之前进行初始化。 (在C++中,非常数表达式可以初始化此类对象或其成员;在这种情况下,初始化发生在块的第一次执行中)。 static
函数声明声明具有内部链接的函数。 extern
声明是正确的,但是第二个(块范围)声明是错误的!static int name; /* external name with internal linkage */
extern int name; /* redundant redeclaration of the above */
void foo(void)
{
int name; /* local variable shadowing external one */
{
/* attempt to "punch through" shadow and reach external: */
extern int name; /* ERROR! */
}
}
extern
关键字中。 static
具有其他含义。在类声明中,它声明“静态成员函数”,这些成员属于类范围,并且与非静态成员函数具有对类实例的相同访问权限,但不会在对象上调用(不具有隐式this
参数)。标记为static
的类数据成员具有单个类范围的实例;它们不是按对象实例化的。 (不幸的是,它们没有像真正的面向对象的类变量那样正确地参与继承,可以在派生类中将其重写为实例,反之亦然。)namespace
而不是static
来实现类似于内部链接的隐私。命名空间使内部/外部链接概念在大多数情况下都不符合C兼容性。 extern
语法(例如extern "LANG"
)包含extern "C"
。 static_cast
与static
无关;它们的共同点是“静态”,意思是“在程序运行之前”:静态存储是在运行之前确定的,静态转换的转换也是在编译时确定的(没有运行时类型信息)。 关于c++ - 静态与新建/Malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21008297/