C + + introductory learning notes 3 - data sharing and protection

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

  1. #if constant expression 1
    //Segment 1
    #elif constant expression 2
    //Segment 2
    #elif constant expression 2
    //Segment 3
    #else 
    //Segment 4
    #endif
    
  2. #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 
    
  3. #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  
    
  4. 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

Keywords: C++

Added by uberpolak on Mon, 17 Jan 2022 05:36:41 +0200