关于我年久失修的C++的康复记录9

Chapter 9 Memory Model and Namespace

0.Before Everything

这是一份四年没有学过C++的菜鸡由于公司业务需求重拾C++的复习记录,因为工作需要在练习英文,加上Ubuntu下输入法与IDE的冲突,所以写纯英文的笔记,顺便练习一下自己英文的水平,如果有表达不当或理解错误,还请看到的大佬提醒我,共勉,谢谢。

9.1 Separate Compilation

1.What is separate compilation and linker.

C++ allows programmer to put component function in a independent file and compile this file separately. If any file is
modified, it could be compiled separately. Compiler producing a file for every source file called an object file which
contains machine language instructions.

It’s the job of a program called a linker to link a project’s object files together into a single executable file. The
linker is responsible for associating all references to a name in one object file to the definition of the name, which
might be in another object file. This process is called address resolution.

2.The header file

A header file usually contains the following items:

  1. Function prototype
  2. Constant value defined with #define or const
  3. Structure declaration
  4. Class declaration
  5. Template declaration
  6. Inline function

Don’t put a function implementation or a variable declaration in a header file.

This may cause conflicts when multiple files include one header file which defines
a variable or a function.

Usually, we define a header file like:

#ifndef HEADER_FILE_NAME
#define HEADER_FILE_NAME
...
#endif

This form can tell compiler to ignore the content except the first time it be included.

The marco name we defined could be capitalized file name with underline as a separator, which is a name that is almost
impossible to be defined in other file.

9.2 Storage persistence, scope and linkage

1.Storage persistence

There are three ways (four in C++ 11) to store data:

  1. Auto storage persistence: Variables declared in a function implementation (including parameters ) is continuously
    stored automatically. It is created when function starts and released when function ends.
  2. Static storage persistence: Variables declared outside a function or declared with static. It runs through the whole
    execution process of the program.
  3. Linear storage persistence (only C++ 11): Variables declared with thread_local have a same life cycle with the thread.
  4. Dynamical store persistence: Variable declared with new operator have a life cycle from it’s declared to released by delete.

2.Scope and linkage

Scope: Where can it be used.

Scope describes the available range of a name in a file. For example, a variable defined in a function can be used in this function,
but not available in other function. C++ variable’s scope can be:

  1. Local: Local variable can only be used in the code block it be defined in.
  2. Global: Global variable can be used from it defined to the end of this file.
  3. Namespace: Variables defined in a namespace can be used in whole namespace.
  4. Class: Variable defined in a class can be used in this class.

The Scope of function can be class or global(namespace). It can not be local because a local function can only be used by itself, and
this is meaningless.

Linkage: How does it be shared.

Linkage describes how a name shared between different unit. The linkage of a name can be internal or external. Internal means this
name can only be used by the function in one file. External means it can be shared between multiple file. The variables defined with
auto have no linkage because it can not be shared.

3.Five different storage types

Description Persistence Scope Linkage Declaration
Auto Auto Code block N/A In a code block
Register Auto Code block N/A In a code block, with key word register
Static, no-linkage Static Code block N/A In a code block, with key word static
Static, external-linkage Static File External Not in any function
Static, internal-linkage Static File Internal Not in any function, with key word static

4.Storage class specifier and cv-qualifier

Storage class specifiers:

  1. auto (not specifier science C++ 11)
  2. register
  3. static
  4. extern
  5. thread_local (C++ 11)
  6. mutable

Cv-qualifier:

  1. const
  2. volatile

mutable:
Mutable means some fields still could be modified even the structure or class is const.

struct data{
    char name[20];
    mutable int age;
};

const data someone = {"someone", 20};

strcpy(someone.name, "another"); // not allowed
someone.age ++; // allowed

Specifier const constrains program from modifying the member of someone, but the mutable makes
age an exception.

const:
In C++, const make some affections on default storage type. The linkage of global variable is
external by default, while for a const global variable it’s internal.
This means that for C++, a global const definition is equals to static.

5.Function and linkage

By default, the linkage of function is external, which means it can be used in multiple files.
We can use extern to specify that this function is defined in another file, and this is optional.
And we can use static to set linkage to internal, and make this function only can be used in one
file. What’s more, the prototype and definition have to be specified by static.

6.Language linking

Another linkage, named language linking, does some affections on function. Linking a program requires
a unique symbol name for every function. The compiler will do name modification to generate different
symbol name for overload function. For example, spiff(int p) -> spiff_i, while spiff(double a, double b) -> spiff_d_d.
This feature is named C++ language linking.

7.Storage plan and dynamic allocation

Dynamic memory allocation refers to the memory controlled by new and delete. A memory created by new
will exist until it is released by delete.

float * p_floats = new float[20];

This statement create serials of space to hold 20 float numbers. When the code block is executed over, the
pointer p_float will be destroyed, while the memory will continue to exist. If this code block returns this
pointer to another function, it can use this memory until released.

9.3 Namespace

In C++, name could refer to a variable, function, structure, etc. The possibility of name collision increases
as the project going bigger. This collision is called namespace problem. In C++, nowadays, compiler supports
a feature to control the scope of these name. It is namespace.

1.Traditional namespace

Declaration region: Declaration region is where something be declared.
Potential scope: The potential scope of a variable start from it is declared to the end of its declaration region.

2.New feature of namespace

C++ supports a new feature to create a namespace.

namespace Jack{
    double pail;
    void fetch();
    int pal;
    ......
}

This feature provides one way to avoid the collision across two namespaces, and allows other codes to use anything
declared in this namespace.

3.Using declaration and compile order

We don’t expect to specify a name every time we use it. So C++ provides two features to simplify the using of name in a
namespace:

Using declaration:

namespace Jill{
    double fetch;
    void bucket();
}

char fetch;

int main(){
    using Jill::fetch; // put fetch from Jill to local namespace
    double fetch; // not allowed, there is already a local name: fetch
    cin >> fetch; // refers to Jill::fetch
    cin >> ::fetch; // refers to global fetch
}

In the main() function, using Jill::fetch; adds this name to local namespace in main(). And name fetch will cover
the global variable. Every fetch in this function will refer to Jill::fetch.

What’s more, we can use using outside the function to add this name to global namespace.

namespace Jill{
    double fetch;
    void bucket();
}

using Jill::fetch; // put fetch from Jill to global namespace

int main(){
    cin >> fetch; // refers to Jill::fetch
}

int display(){
    cout << fetch; // fetch can be accessed here too
}

Compiler will not allow use using to two variables with same name in different namespace.

using Jill::fecth;
using Jack::fetch;

This declaration will cause ambiguity and must be avoided.

Using compile order:

namespace Jill{
    ...
}

using namespace std;

int main(){
    using namespace Jill;
}

using namespace std; makes everything in std available in this file (global). And
using namespace Jill; makes everything in Jill available in main() function (local).

4.Something about namespace

Suggestions:

  1. Using variable declared in namespace with name rather than external or static global variable.
  2. Putting function lib or class lib to a namespace.
  3. Using using compile order only when need to convert old code to namespace.
  4. Do not use using compile order in header file.
  5. Prefer using scope resolution operators :: when import name.
  6. Prefer local using declaration rather than global.
上一篇:fetch的使用


下一篇:vue3.x fetch 使用