C + + Notes 3
Data sharing and protection
Scope and visibility of identifiers
Scope
There are five scopes, from small to large: function prototype scope – > local scope – > class scope – > file scope – > namespace scope.
-
Function prototype scope
For example: function declaration double area(double radius); The variable radius in the area function only works in the declared parameter list of the area function, that is, from the left of the bracket to the right of the bracket.
-
Local scope (block scope)
The scope of the internally defined variable enclosed by braces is from the beginning of the definition to the end of the braces.
For example, the formal parameters of functions and variables defined in if statements, switch statements, for statements and while statements all comply with the above rules.
Variables with local scope are called local variables.
-
Class scope
A member of a class has a class scope.
It can be accessed directly within classes and member functions. It can be accessed outside the class through x.m (non static member) and X::m (static member); It can also be accessed through object pointers and object references.
-
File scope (also known as static scope)
Identifiers that are not declared in the aforementioned scopes have file scopes. The identifier of the file scope starts at the declaration and ends at the end of the file.
-
namespace scope
For the explanation of namespace scope, see P147 of the fourth edition of C + + programming (Zheng Li).
visibility
Visibility is the smallest and largest identifier in scope
Object lifetime
The object here does not refer to the object in a narrow sense, including simple variables, objects, functions and so on
Static survival
- This lifetime is the same as the running time of the program – > it survives as long as the program is running.
- Objects declared in the file scope have this lifetime
- The static lifetime object should be declared inside the function and preceded with the static keyword
Dynamic survival
- It starts when the program executes to the declaration point and ends at the end of the scope naming the identifier
- The objects declared in the block scope without the static keyword are dynamic lifetime objects
Static member of class
Static data member
Declared inside the class, defined and initialized outside the class.
Static function member
Use the same rules as static data members
It is usually used to operate on static data members
class J{ public: ... static void showCount(); //Declaration of static function members private: static int count; //Declaration of static data members }; int J::count =90; //Definition and initialization of static data members //Note that the definition cannot be modified with static keyword void J::showCount() { //Implementation of static function members outside the class cout << "count:" << count << endl; } int main(){ ... J::showCount(); return 0; } /*Note that this section only shows the code related to static members, and other codes have been omitted When using, add corresponding codes as needed */
Friends
The friend function of the class allows the program to access the data members of the object directly through the object name outside the class (the friend function is not the member function of the class), thus bypassing the external interface of the class and improving the efficiency of the program. Sometimes, programmers must choose between efficiency and data security. They can make a reasonable choice between them through friend functions.
- > tips: when using an object as a function parameter, it is more efficient to pass the reference of the object directly than the data of the whole object. But there are hidden dangers in passing references directly.
friend function
Use of friend functions:
class Point { public: Point(int x=0,int y=0):x(x),y(y){}//Constructor int getX() { return x; } int getY() { return y; } friend float dist(Point &p1, Point& p2); //Friend keyword is used in the declaration of friend function private: int x, y; }; float dist(Point &p1, Point& p2) { //The friend function is implemented outside the class without friend modification double x = p1.x - p2.x; double y = p1.y - p2.y; return static_cast<float>(sqrt(x*x + y*y)); //static_cast cast cast } int main() { Point p1(1, 1); Point p2(2, 2); cout << dist(p1, p2) << endl; return 0; }
- Using friend functions, you can access the private and protected members of an object through the object name outside the class
Friend class
If a class is a friend of another class, all function members of this class can access all private members of another class.
If class A is a friend class of class B, all member functions of class A are friend functions of class B and can access private and protected members of class B.
P161
Declaration syntax: use the friend keyword to declare the class name of the friend class in the class.
The relationship between friends is one-way. If a is a friend class of B, B may not be a friend class of A.
Protection of shared data
Data protection is mainly realized through const keyword.
Note: const keyword is different from static. Const should be used when members (data members and function members) are declared. It must also be carried at the initialization of data members and the implementation of function members. In short, the identifier modified by const should carry const whenever it appears.
Constant type:
Constant object
Declaration method: const type object name;
A constant object cannot have its data members updated throughout its lifetime.
Constant objects must be initialized and cannot be updated.
Constant function
-
Constant functions can be called by constant objects or ordinary objects.
-
A constant object can only call constant member functions and cannot call other member functions
-
A constant member function cannot update the data member of the destination object because when a constant member function is called, its destination object is treated as a constant object.
-
const keyword can distinguish function overloading
The const modifier should be used for member functions that do not need to change the object state
class R { public: R(int r1,int r2):r1(r1),r2(r2){} //Constructor void print() { //Ordinary member function cout << r1 << ":" << r2 << endl; //This ordinary print() function can also be omitted. If deleted, r call the print function modified by const } void print() const { //Constant member function cout << r1 << "---:---" << r2 << endl; } private: int r1, r2; }; int main() { R r(2, 3); r.print(); //Object r calls the normal member function print() const R rcon(4, 4); rcon.print(); //The rcon object calls the constant function print() return 0; } /*Output results: 2:3 4---:---4 */
Constant data member
Both static data members and non static members can be decorated with const.
Constant members can only initialize assignments and cannot assign assignments elsewhere.
- const members fall into two categories: static and non static
static: directly initialized outside the class. Initialization cannot be performed inside the main function
Non static member: initialized through the initialization list of the constructor of the class. Note: non static members decorated with const cannot be assigned in the constructor body.
class R { public: R(int i); void print() { cout << r1 << ":" << r2 << endl; } private: static const int r1; const int r2; }; R::R(int i) :r2(i) {} //Non static data members are modified by const and can only be initialized in the initialization list of the constructor const int R::r1 = 5; //Static const can only be initialized outside the class and inside a non main function int main(){ R a(66); a.print(); return 0; }
Often cited
Objects referenced by constant references cannot be updated
If you use a constant reference as a formal parameter, you will not accidentally change the argument
Multi file structure
First, an explanation on the multi file structure of C/C + + project is attached: An explanation of C/C + + project multi file structure CSDN
For example, we can change the Point file structure to multiple programs.
- File Point Write the declaration of Point class in H;
- File Point_shixian.cpp needs to contain Point The implementation of each member function of class Point and the processing of constant data members are written in the H header file.
- main.cpp needs to contain Point H header file. Implements the use of the Point class.
Each CPP file is compiled with suffix obj file, and then put all obj file is connected with the system runtime to become an executable file (xxx.exe)
External variable
External variable: it can be used not only in the source file that defines it, but also in other source files.
- All variables defined in the file scope are external variables by default (int a;)
- When using variables defined in other source files, declare them in this file (extern int a;) Then it can be used.
External function
External functions: functions declared outside the class (i.e. non member functions) are external functions with file scope
- External functions can be called in other compilation units
- Before calling functions defined in other source files, the function prototype must be declared in this file.
Usually, the definitions of variables and functions are placed in the source file, while the referential declarations of external variables and functions are placed in the header file.
How to hide the variables and functions defined in this file from other source files?
Such variables and functions can be defined in anonymous namespaces.
namespace {//anonymous namespace int b_yincang; void print_b() { cout << "b = " << b_yincang << endl; } }
Compile preprocessing instructions
#include instruction
#The include directive can be nested. Suppose there is a header file myhead h. The header file can have
The following files contain instructions:
#include "file1.h"
#include "file2.h"
P173
- #Include < >, which is generally used to include the header file of the system. When used in this way, the system will search the included file in the standard way, that is, first search from the default include folder of the system
- #include "" is generally used to contain custom header files. When using this method, the compiler will first search in the current directory. If not, it will search in the standard way.
#define directive and #undef directive
#The define instruction is often used in C language, but there is a better way to replace it in C + +. All #define instructions are often used to define empty symbols, such as
#define MYHEAD_H. The purpose of defining it is only to indicate that "MYHEAD_H has been defined". It is used together with conditional compilation instructions, which is a common way in C + +.
#The undef instruction is used to delete #define defined symbols so that they no longer work
Conditional compilation instruction
Multiple forms of use
-
#if constant expression 1 //Segment 1 #elif constant expression 2 //Segment 2 #elif constant expression 2 //Segment 3 #else //Segment 4 #endif
-
#ifdef identifier //If the identifier is #define defined and not #undef deleted, compile segment 1 Segment 1 #else // Else can be deleted if not required Segment 2 #endif
-
#ifndef identifier / / if identifier 1 is not defined, compile program segment 1; otherwise, compile program segment 2 Segment 1 #Else / / else can be deleted if not needed Segment 2 #endif
-
defined operator
Defined is a preprocessing operator, so it does not need to be # marked. The usage method is: defined (identifier). If the identifier is defined, the above expression is non-zero, otherwise it is zero.
The following two expressions are completely equivalent:
#ifndef MYHEAD_H # define MYHEAD_H Segment 1 #endif //Equivalent to #if !defined(MYHEAD_H) #define MYHEAD_H Segment 1 # endif
One of the functions of using conditional compilation instructions is to prevent repeated definition errors of classes and variables caused by multiple inclusion of a header file. (the reason for this error is that the #include directive can be nested, that is, the header file can be nested to contain)
See P176 for details
It does not need to be # numbered. The usage method is defined. If the identifier is defined, the above expression is non-zero, otherwise it is zero.
The following two expressions are completely equivalent:
#ifndef MYHEAD_H # define MYHEAD_H Segment 1 #endif //Equivalent to #if !defined(MYHEAD_H) #define MYHEAD_H Segment 1 # endif
One of the functions of using conditional compilation instructions is to prevent repeated definition errors of classes and variables caused by multiple inclusion of a header file. (the reason for this error is that the #include directive can be nested, that is, the header file can be nested to contain)
See P176 for details