这是一份四年没有学过C++的菜鸡由于公司业务需求重拾C++的复习记录,因为工作需要在练习英文,加上Ubuntu下输入法与IDE的冲突,所以写纯英文的笔记,顺便练习一下自己英文的水平,如果有表达不当或理解错误,还请看到的大佬提醒我,共勉,谢谢。
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.
A header file usually contains the following items:
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.
There are three ways (four in C++ 11) to store data:
thread_local
have a same life cycle with the thread.new
operator have a life cycle from it’s declared to released by delete
.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:
- Local: Local variable can only be used in the code block it be defined in.
- Global: Global variable can be used from it defined to the end of this file.
- Namespace: Variables defined in a namespace can be used in whole namespace.
- 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.
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 |
Storage class specifiers:
Cv-qualifier:
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.
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
.
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.
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.
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.
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.
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.
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).
Suggestions:
using compile order
only when need to convert old code to namespace.using compile order
in header file.::
when import name.using declaration
rather than global.