静态与新/Moloc
Static vs New/Malloc
我想知道人们是否可以了解"static"的用法。我从未遇到过明确声明变量或方法为static的问题。我知道,当将某个东西声明为"静态"时,它会被填充到程序的数据段中,类似于全局变量,因此该变量可以用于程序的运行。如果是这样的话,为什么不把一个静态变量变成全局变量呢。见鬼,为什么不使用一个新的或malloc将这个变量扔到堆上呢?这两种方法都可以确保在程序的整个运行过程中都可以使用这个变量。
static
在C中有多种含义,C++甚至有更多含义。
在文件范围声明中(我认为问题是关于这个),static控制标识符的可见性。
让我们把C++放在一边,使用C的概念。
文件范围标识符,用于命名具有链接的对象或函数。链接可以是外部(程序范围)或内部,(在一个翻译单元内)。
static
指定内部链接。
这一点很重要,因为如果一个具有内部链接的名称出现在多个单元中,则这些出现是不相关的。一个模块可以具有静态foo
功能,而同一程序中的另一个模块则可以具有不同的foo
功能。它们都存在,并且可以通过名称foo
从它们各自的单元访问。
这在外部链接中是不可能的:必须有一个foo
。
malloc
创建一个对象,该对象可能在程序中的任何地方都可用,只要它没有被释放,而是在不同的意义上。如果有对象的指针,则该对象可用。指针是一种"运行时名称":用于访问对象的访问键。如果您知道一个对象或函数的名称(在编译时),并且该对象和函数相对于您试图访问它的位置具有正确的链接类型,则链接使其可用。
在一个动态操作系统中,多个程序开始运行并终止,其静态数据和功能(无论它们是否具有外部或内部链接)的存储实际上是动态分配的。加载程序的系统例程必须执行类似于malloc
的操作,以获取程序的所有固定区域的内存。
有时C程序甚至对通过全局指针全局引用的"singleton"对象使用malloc
。这些对象的行为类似于事实上的静态变量,因为它们的生存期基本上相当于整个程序的生存期,并且是通过指针访问的,指针是按名称访问的。如果对象具有直到运行时才知道的属性(如大小),或者如果它们的初始化成本很高并且并不总是需要它们(仅当程序中出现某些情况时),则此选项非常有用。
关于static
和extern
的补充事实:
-
在C中,在文件范围内,
extern
确保省略了初始值设定项的对象声明实际上是一个声明。如果没有extern
,它只是一个暂定的定义,但如果存在初始值设定项,那么它就是一个定义。 -
在C中,在文件范围
extern
并不意味着"该声明具有外部链接",这令人惊讶。extern
声明继承了以前同名声明的链接。 -
C中的块作用域
extern
的意思是"引入该作用域的名称是指具有外部链接的外部定义"。链接是从名称的上一个文件作用域声明继承的(如果存在),否则是外部的。 -
对象上的块作用域
static
控制的不是链接,而是存储持续时间。CCD_ 18对象在每次进入块时不被实例化;存在它的单个副本,并且可以在程序启动之前进行初始化。(在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! */ } }
-
显然,"外部"一词在"任何功能之外"answers"程序范围内的链接"之间有着模糊的含义,这种模糊性与
extern
关键字有关。 -
在C++中,
static
具有额外的含义。在类声明中,它声明"静态成员函数",这些函数属于类作用域,与非静态成员函数具有相同的类实例访问权限,但不会在对象上调用(没有隐式this
参数)。标记为static
的类数据成员具有单个类范围的实例;它们不是按对象实例化的。(不幸的是,它们不像真正的面向对象类变量那样正确地参与继承,后者可以在派生类中重写为实例,反之亦然。) -
在C++中,使用未命名的
namespace
而不是static
可以实现类似于内部链接的隐私。名称空间使得内部/外部链接概念在很大程度上成为C兼容性的过时机制。 -
C++在特殊的
extern "LANG"
语法(例如extern "C"
)中涉及extern
。 -
CCD_ 30与CCD_;它们的共同点是"static",意思是"在程序运行时之前":静态存储在运行时之前确定,静态类型转换也在编译时确定(没有运行时类型信息)。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 私有类型的静态常量成员
- 使用gcc从静态链接的文件中查找可选符号
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 如何在C++中使用非静态成员函数作为回调函数
- 将静态库链接到不带-fPIC的共享库中
- 静态结构和一个定义规则
- 为什么虚函数不能是静态的和全局的?
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 静态与新/Moloc