C++ essentials 之 static 关键字
extraction from The C++ Programming Language, 4th. edition, Bjarne Stroustrup
1. If no initializer is specified, a global, namespace, local static
, or static
member (collectively called static objects) is initialized to {}
of the appropriate type.
2. We classify objects based on their lifetimes:
- Automatic: Unless the programmer specifies otherwise, an object declared in a function is created when its definition is encountered and destroyed when its name goes out of scope. Such objects are sometimes called automatic objects. In a typical implementation, automatic objects are allocated on the stack; each call of the function gets its own stack frame to hold its automatic objects.
- Static: Objects declared in global or namespace scope and
static
s declared in functions or classes are created and initialized once (only) and "live" until the program terminates. Such objects are called static objects. A static object has the same address throughout the life of a program execution. Static objects can cause serious problems in a multi-thread program because they are shared among all threads and typically require locking to avoid data races. - Free store: Using the
new
anddelete
operators, we can create objects whose lifetimes are controlled directly. - Temporary objects (e.g., intermediate results in a computation or an object used to hold a value for a reference to
const
argument): their lifetime is determined by their use. If they are bound to a reference, their lifetime is that of the reference; otherwise, they "live" until the end of the full expression of which they are part. A full expression is an expression that is not part of another expression. Typically, temporary objects are automatic. - Thread-local objects; that is, objects declared
thread_local
: such objects are created when their thread is and destroyed when their thread is.
Static and automatic are traditionally referred to as storage classes.
Array elements and nonstatic class members have their lifetimes determined by the object of which they are part.
3. An array can be allocated statically, on the stack, and on the free store. For example:
int a1[10]; // 10 ints in static storage
void f(){
int a2[20];
int *p = new int[40]; // 40 ints on the free store
// ...
}
4. A string literal is statically allocated so that it is safe to return one from a function. For example
const char* error_message(int i){
// ...
return "range error"
}
5. [10.4.5] (??) The address of a statically allocated object, such as a global variable, is a constant. However, its value is assigned by the liker, rather than the compiler, so the compiler cannot know the value of such an address constant. That limits the range of constant expressions of pointer and reference type. For example:
constexpr const char *p1="asdf";
constexpr const char *p2=p1; // OK
constexpr const char *p2=p1+2; // error: the compiler does not know the value of p1
constexpr char c=p1[2]; // OK, c=='d'; the compiler knows the value pointed to by p1
6. [11.2.2] (??) To deallocate space allocated by new
, delete
and delete[]
must be able to determine the size of the object allocated. This implies that an object allocated using the standard implementation of new
will occupy slightly more space than a static object. At a minimum, space is needed to hold the object's size. Usually two or more words per allocation are used for free-store management. Most modern machines use 8-byte words. This overhead is not significant when we allocate many objects or large objects, but it can matter if we allocate lots of small obejects (e.g., int
s) on the free store.
7. A member function may be specified as static
, indicating that it is not associated with a particular object.
8. [12.1.8] A name defined in a function is commonly referred to as a local name. A local variable or constant is initialized when a thread of execution reaches its definition. Unless declared static
, each invocation of the function has its own copy of the variable. If a local variable is declared static, a single, statically allocated object object will be used to represent that variable in all calls of the function. It will be initialized only the first time a thread of execution reaches its definition (rather than at compile time). For example:
void f(int a){
while(a--){
static int n=0; //initialized once
int x=0;
cout<<"n == "<<n++<<", x == "<<x++<<'\n';
}
}
A static
local variable allows the function to preserve information between calls without introducing a global variable that might be accessed and corrupted by other functions.
Initialization of a static local variable does not lead to a data race unless you enter the function containing it recursively or a deadlock occurs. That is, the C++ implementation must guard the initialization of a local static variable with some kind of lock-free construct (e.g., a call_once;). The effect of initializing a local static recursively is undefined. For example:
int fn(int n){
static int n1=n; // OK
static int n2=f(n-1)+1; //undefined
return n;
}
A static local variable is useful for avoiding order dependencies among nonlocal variables.
9. A variable defined without an initializer in the global or a namespace scope is initialized by default. This is not the case for non-static
local variables or the objects created on the free store.
10. A name that can be used in translation units different from the one in which it was defined was said to have external linkage. A name that can be referred to only in the translation unit in which it is defined is said to have internal linkage. For example:
static int x1=1; //internal linkage
const char x2='a'; //internal linkage
When used in namespace scope (including the global scope), the keyword static
(somewhat illogically) means "not accessible from other files" (i.e., internal linkage). If you wanted x1
to be accessible from other source files ("have external linkage"), you should remove the static
. The key word const
implies default internal linkage, so if you wanted x2
to have external linkage, you need to precede its definition with extern
:
int x1=1; // external linkage
extern const char x2='a'; // external linkatge
Names that a linker does not see, such as the names of local variables, are said to have no linkage.
11. In principle, a variable defined outside any function (that is, global, namespace, and class static
variables) is initialized before main()
is invoked. Such nonlocal variables in a translation unit are initialized in their definition order. If such variable has no explicit initializer, it is by default initialized to the default for its type.
12. A variable that is part of a class, yet is not part of an object of that class, is called a static
member. There is exactly one copy of a static
member instead of one copy per object, as for ordinary non-static
members. Similarly, a function that needs access to members of a class, yet doesn't need to be invoked for a particular object, is called a static member function.
A static
member can be referred to like any other member. In addition, a static
member can be referred to without mentioning an object. Instead, ins name is qualified by the name of its class.
if used, a static
member--function or data member--must be defined somewhere. The keyword static
is not repeated in the definition of a static
member.
In multi-threaded code, static
data member require some kind of locking or access discipline to avoid race conditions. Since multi-threading is now very common, it is unfortunate that use of static
data members was quite popular in older code. Older code tends to use static
members in ways that imply race conditions.
13. A static
class member is statically allocated rather than part of each object of the class. Generally, the static
member declaration acts as a declaration for a definition outside the class. For example:
class Node{
// ...
static int node_count; // declaration
};
int Node::node_count=0; // definition
However, for a few simple special cases, it is possible to initialize a static
member in the class declaration. The static
member must be a const
of an integral or enumeration type, or a constexpr
of a literal type, and the initializer must be a constant-expression. For example:
class Curious{
public:
static const int c1=7; // OK
static int c2=11; // error: not const
const int c3=13; // OK but not static
static const int c4=sqrt(9); //error: in-class initializer not constant
static const float c5=7.0; //error: in-class not integral (use constexpr rather than const)
// ...
};
If (and only if) you use an initialized member in a way that requires it to be stored as an object in memory, the member must be (uniquely) defined somewhere. The initializer may not be repeated:
const int Curious::c1; // don't repeat initializer here
const int *p = &Curious::c1; // OK: Curious::c1 has been defined
Note that const int Curious::c1;
is definition of Curious::c1
which is declared in Curious
as static const int c1;
.
C++ essentials 之 static 关键字的更多相关文章
- 浅谈Static关键字
1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ...
- (转)Java中的static关键字解析
转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...
- PHP的final关键字、static关键字、const关键字
在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...
- Java Static关键字详解
提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的 ...
- 关于Java中的static关键字
Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键. Java中的 static 关键字主要是用来做内存管理的.理解了这句话才能够比较 ...
- Java中的static关键字解析
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
- c++中static关键字的用法总结
类中的静态成员真是个让人爱恨交加的特性.我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动. 静态类成员包括静态数据成员和静态函数成员两部分. 一 静态数据成员: 类体中 ...
- static关键字
static关键字 static是静态修饰符,一般修饰成员.被static修饰的成员属于类,不属于单个这个类的某个对象. 1.static关键字的特点 a:随着类的加载而加载 b:优先于对象存在 (还 ...
- C++中的static关键字的总结
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...
随机推荐
- 眼保Guide
1.睡前不要玩手机,特别是关灯玩手机!否则第二天早上你就会感到眼睛模糊了.长久下去就会形成近视或者近视加深. 2.早上起床半小时内不要戴眼镜,不要看手机.电脑等一切电子屏幕,甚至不要看书.这段时间是眼 ...
- cocos2dx-2.2.1 免 Cygwin 环境搭建(Win8+VS2013+ADT Bundle+android-ndk-r9c)
1.下载 ADT Bundle 解压到D盘 D:\adt-bundle-windows-x86_64-20131030: 2.下载 NDK-R9C,解压到 ADT 目录下:D:\adt-bundle- ...
- Tensorflow学习笔记2:About Session, Graph, Operation and Tensor
简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...
- 揭秘Facebook首个数据中心:全球15亿用户的账户信息都在这里
投递人 itwriter 发布于 2016-07-14 17:41 评论(0) 原文链接 [收藏] 对于 Facebook.Google 这种体量的科技公司而言,数据中心应该是处于军事级别的保密 ...
- Excel——将内容导出
using (FileStream fsRead = File.OpenRead("111.xls")) { IWorkbook wk = new HSSFWorkbook(fsR ...
- 1121高性能MySQL之运行机制
本文来自于拜读<高性能MySQL(第三版)>时的读书笔记作者:安明哲转载时请注明部分内容来自<高性能MySQL(第三版)> MySQL的逻辑构架 MySQL服务器逻辑架构 最上 ...
- Yii2初级入门教程
下载安装 Yii挺火的,也是MVC的Web框架.国内占有率,相当不错.值得一学. 网络上提供了两个版本模板的下载, advanced, 和 basic, 使用起来一致, 提供的模块支持不同. Adva ...
- jq实现登陆页面的拖拽功能
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <script src ...
- 50ms延时程序
12MHz晶振 一个机器周期2us, DEL: MOV R7,#200D DEL1: MOV R6,#125 DEL2: DJNZ R6,DEL2 ;125*2=250us DJNZ R7,DE ...
- 利用springframework+javax.mail发邮件(普通邮件、带附件邮件、HTML格式邮件)
Spring提供了发送电子邮件的支持,可以发送普通邮件.带附件邮件.HTML格式邮件,甚至还可以使用Velocity模板定制化邮件内容. 一.引入相关的库 1 2 3 4 5 6 7 8 9 10 1 ...