thinking in c++之Name control

最近在阅读thinking in c++,通过这个博客记录下学习中遇到的一些比较重要的知识点。现在看到了第10章,前面的几个章节之前阅读时没有这种记录的意识,等有时间,再重新翻看下,再记录吧。


第10章的Name Control主要是介绍了static和namespace如何控制变量的作用域。

Static elements from C

In both C and C++ the keyword static has two basic meanings:    包括C和C++,关键词static都有两个基本的意义:

1.Allocated once at a fixed address.   只在固定的地址上分配一次空间

2.Local to a particular translation unit(and local to a class scope in c++). Here, static controls the visibility of a name, so that name can't be seen outside the translation unit or class.  让变量本地到特定的编译单元中(也本地到C++的类作用域中)。这里,static控制了命名的可见性,因此命名不能给被编译单元或者类之外所见。


static variables inside functions

C and C++ allow you to create a static object inside a function; the storage for this object is not on the stack but instead in the program's static data area.This object is initialized only once, the first time the function is called, and then retains its value between functions invocations.

C和C++允许你在函数内部创建一个static 对象;这个对象的内存空间并不在栈中,而是在程序的静态存储区域。这个对象只在函数第一次被调用时初始化,之后在函数调用时都保留它的值。

but if you do not provide an initializer  for a static variable of a built-in type,the compiler guarantees that variable will be initialized to zero(converted to the proper type) at program start-up.

但是如果你没有给内置类型的static 变量提供一个初始化值,编译器会保证将变量初始化为0(0会被转换为合适的类型),在程序启动的时候。

这个时候,可能你就好奇了,那如果static对象不是内置类型呢??稍候莫急。

static class object inside functions

user-defined types must be initialized with constructor calls.   用户自定义的类型必须通过构造函数初始化。

static object destructors

Destructors for static objects (that is, all objects with static storage,not just local static objects ) are called when main() exits or when the Standard C library function exit() is explicitly called.Static object destructors are not called if you exit the program using the Standard C library function abort().    

静态对象的析构函数(也就是说,是所有静态存储区的对象,不单是局部静态对象)被调用,当main()退出或者C标准库函数exit()被显示调用。静态对象的析构函数并不被调用,当程序是使用C标准库函数abort(0退出时。

Global objects are always constructed before main() is called and destoryed as main() exits. 
全局变量总是在main()调用之前被构造,当main()退出时被销毁。

controlling linkage

 Ordinarily,any  name at file scope(that is ,not nested inside a class or functions) is visible throughout all translation units in a program. This is often called external linkage because at link time the name is visible to the linker everywhere, external to that translation unit. 

通常,文件范围内的名称(也就是说,名称没有嵌套在类中或者函数中)贯穿程序的所有编译单元中都是可见的。这也经常被叫做外部连接,因为在连接时期,名称在连接器的任何一个地方是可见的,外部到编译单元。

An object or function name at file scope that is explicitly declared static is local to its translation unit. That name has internal linkage.This mean you can use the same name in other translation units without a name clash.

在文本范围内,一个用static声明的对象或函数名对于这个编译单元来说是本地的,那个变量有内部链接。这意味着你可以在其他的编译单元中使用相同的名称,而不用担心命名冲突。


One advantage to internal linkage is that the name can be placed in a header file without worrying that there will be a clash at link time.Name that are commonly place in header files,such as const definitions and inline functions,default to internal linkage.However,const defaults to internal linkage only in C++; in C it defaults to external linkage .

内部链接的一个好处是我们可以将一个命名放到头文件中而不用担心在连接时产生冲突。命名经常被放在头文件中,例如const 定义和内联函数,默认是内部连接。然而,const定义只有在C++中才默认为内部连接,在C中,默认是外部链接。


Namespace

Creating a namespace


There are significant differences from class,struct ,union and enum .however:

  • A namespace definition can appear only at global scope ,or nested within another namespace.
  • No terminating semicolons is necessary after the closing brace of a namespace definition.
  • A namespace definition can be "continued" over multiple header using a syntax that, for a class, would appear to be a redefinition.
//: C10:Header1.h
#ifndef HEADER1_H
#define HEADER1_H

namespace Mylib
{
    extern int x;
    void f();
}

#endif  //HEADER1_H

//: C10:Header2.h

#ifndef HEADER2_H
#define HEADER2_H

#include "Header1.h"

//add more names in Mylib

namespace Mylib{ //
   extern int y;
   void g();
  //...
}


#endif  //HEADER2_H

//: C10:Continuation.cpp

#include "Header2.h"

int main(){}


  • A namespace can be aliased to another name , so you don't have to type an unwieldy name created by a library vendor:
namespace BobsSuperDuperLibrary
{
    class Widget{};
    class Poppit{};
}

//Too much to type.then i can alias it
namespace Bog = BobsSuperDuperLibrary;

int main(){}
  •       You cannot create an instance of a namespace as you can with a class.

namespace 和class,struct,union和enum有显著的不同,然而:
  • 命名空间的定义只能出现在全局范围内或者嵌套在另外一个命名空间中。
  • 命名空间定义完后的右大括号后不必有分号。
  • 一个命名空间可以在多个头文件中连续定义,使用这语法,对于class来说,将会出现重复定义。
  • 一个命名空间可以用别的名字作为别名,所以你就不必输入库供应商创建的笨重的名称。
  • 你不能为一个命名空间创建实例,就像你对class做的那样。

今天就到这里了。敲的手酸


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值