Day_05 special members (const, static) and friends

1.const

(1) . const member data

        const modifier can modify member data or member functions. When decorating member data, it means that member data cannot be changed. And the member function can only be assigned by initializing the list (or give it an initial value when defining the data member).

class MM{
public:
    MM(){string name,int age}:name(name),age(age){
            
    }
    void print(){
        //age=22;   Once the error has passed the initialization parameter list, it cannot be modified
     }
protected:
    const int age = 10;
    string name; 
}

(2) const member function

        const member functions can use all member variables in the class, but their values cannot be modified. This measure is mainly set to protect data. const member functions are also called constant member functions.

        A constant member function can have the same function name as a member function. When calling a function method, call the ordinary member function first. If the ordinary function cannot be found, the constant member function will be called.

class MM{
public:
    MM(){string name,int age}:name(name),age(age){
            
    }
    void print(){
        //age=22;   Once the error has passed the initialization parameter list, it cannot be modified
     }
    //Constant member function
    void print() const{
        //string name = "xx" wrong writing
        cout<<name<<endl;
    }
protected:
    const int age = 10;
    string name; 
}

(3) const constant object

        It is the same as ordinary definition objects, except that ordinary definition objects are preceded by a cosnt modifier. But unlike ordinary objects, constant objects can only call constant member functions. Ordinary member functions cannot be called. Ordinary objects can call both ordinary member functions and constant member functions. However, when the constant member function and the ordinary member function have the same name, the ordinary object cannot force the constant member function to be called.

const MM m1;    //Define a parameterless object

Summary:

+const data member
  + const type variables are not modifiable and are in read-only mode
  + Initialization must be performed in the form of initialization parameter list


+const member function
  + In terms of writing, const is written after the function
  + A constant member function is a read-only data member that cannot be modified
  + Constant member functions can exist simultaneously with ordinary functions
            + When ordinary functions and constant member functions are the same, ordinary objects call ordinary functions first
            + Ordinary objects can call constant member functions


+Const object: const decorated object
  + A constant object can only call constant member functions

2.static

        Static members do not belong to objects, but belong to classes, which means that they are common to all objects. Objects are not required for calling. Of course, you can call them with objects (provided that the static data members defined under public) that is, the static data members are still limited by permissions.

(1) . static member data

         The member data defined by static can only be initialized outside the class (the assignment is also wrong when defining). Static does not need to be added when initializing outside the class, but the class name qualification needs to be added.

class MM{
public:
    //Wrong writing. Static data members cannot be initialized by initializing the parameter list
    //MM(string name,int age):name(name),age(age){};
protected:
static string name;
static int age;
}

//Static member data must be initialized outside the class, not inside the class
int MM::age=20;
string MM::name="xxx";

          Let's take a look at an example to better understand the concept that static member variables are public in a class.

class MM{
public:
	//Variables of type static cannot be initialized by initializing the parameter list
	MM(string name=" ") :name(name){
		num++;
	}

	//Static member function
	static void printMM();

protected:
	string name;
public:
	static int num;
};

int MM::num=0;

int main(){
    MM m1("xx");
    cout<<MM::num<<endl;      //num=1
    MM m2[3];
    cout<<MM::num<<endl;      //num=4
    MM* m3=new MM("zz");        
    cout<<m3.num<<endl;       //num=5
    return 0;
}

        In the code, the static data member num in the MM class will increase with the call of the constructor. Every time a constructor is called, it will be num+1, and finally, the 5 constructor num=5 is called.

(2) . static member function

        Add a static modifier to the member function. Like static member data, static is not required for implementation outside the class, just add the class name qualification.

class MM{
public:
	MM(string name=" ") :name(name){
		num++;
	}
	//Static member function
	static void printMM();
protected:
	string name;
public:
	static int num;
};

//Class name qualification is required to implement static member functions outside the class
void MM::printMM(){
    cout<<"Static member function"<<endl;
}

         However, it should be noted that the object must be specified when the static member function calls the non static member data. It is easy to understand (static member functions belong to classes and are common to each object. For non static member data, the corresponding values of each object are different. Without specifying the object, the static member function does not know which to access.)

3. Friends

        Friends just provide a place to give objects permission to break classes (ignoring permissions). Add friend before the function. Note: friend functions do not belong to a class (not member functions) and cannot directly access the member data in the class. However, in the friend function, the object can directly access the member data in the class without permission restriction.

(1) 2. Ordinary friend function

         Member functions implicitly increase this when called   Pointer , point to the object that calls it, so as to use the members of the object; show() is a non member function without this pointer. The compiler does not know which object member to use. To make this clear, you must pass the object through parameters (you can pass the object directly, or pass the object pointer or object reference), and specify the object when accessing the member.

class MM{
public:
    MM(){string name,int age}:name(name),age(age){
            
   }
    //friend function
   friend void print(MM& mm){
      //The following is the wrong way of writing
        cout<<name<<" "<<age<<endl; Wrong writing friend function does not belong to class and cannot directly access member data
        //You need to pass in an object or a reference to an object
        cout<<mm.name<<" "<<mm.age<<endl;    
   }
protected:
    int age = 10;
    string name; 
}
int main(){
    MM m(" ",22);
    //Call friend functions to access member data directly
    print(mm);
    return 0;
}

         Friend functions do not belong to a class, so when friend functions define out of class implementations in a class, they do not need to be qualified by class name or modified by friend.

        Because a friend function does not belong to a class, it cannot directly access non static member variables in the class!!!

         Because a friend function does not belong to a class, it cannot directly access non static member variables in the class!!!

         Because a friend function does not belong to a class, it cannot directly access non static member variables in the class!!!

(2) . take the member function of another class as a friend function (it's easy to make mistakes)

        It is also a friend function in essence.

        Example: take the member function in class B as the friend function of a: first write class B and declare the member function. Then write class A, declare the friend function, and then implement the member function of class B outside the class. This order cannot be modified.

//An example of a friend function whose member function of class B is class A
class B{
public:
    void printA();
protected:
}

class A{
public:
    //Shen Mingyou function
   friend void B::printA();
protected:
    string name="A";
}
//Member function implementation
void B::printA(){
    //Friend functions in class a can break through the restrictions of class and directly access the protection attributes of class A
    A a;
    cout << a.name << endl;
}

 

(3) 2. Friend category

        If you declare another class as a friend class in a class, the other class can access it

#include<iostream>
#include<string>
using namespace std;

//Go ahead and make it clear
class B;

class A{
public:
	A(string name) :name(name){ }

	void print();

	void printData(B& b);
protected:
	string name = "A";
};

class B{
public:
	B(string name = "B") :name(name){ }
	//Declare that B is a friend class of A
	friend class A;        //All member functions in A are friend functions of B
protected:
	string name = "B";
};
void A::print(){
	B b;
	cout << b.name << endl;

}
void A::printData(B& b){
	cout << b.name << endl;
}
int main(){
	B b;
	A a("A");
	a.print();
	a.printData(b);

	return 0;
}

        The above statement states that class A is a friend of class B, then all member functions in class A are friend functions of class B, and the permission limit of class can be ignored. (in order to prevent undefined problems, it is better to define member functions outside the class and add the preceding declaration of the class)

 

4.this pointer and explicit

          explicit is used to modify the constructor. It is used to restrict implicit conversion when creating an object (restrict the way of equal sign assignment to create an object).

class MM{
public:
	//explicit limit implicit conversion
	explicit MM(int age) : age(age){

	}

	void printThis(){
		cout << this << endl;
	}
protected:
	int age;
};

int main(){
    //Implicit conversion, you can create objects without explicit.
    //MM m=20;
    
    //Constructor with explicit modifier cannot be implicitly converted
    MM m(20);
    return 0;
}

        this pointer can avoid the problem caused by the same formal parameter name and data member name of non static member function.

        This pointer can also return the object itself. Without this pointer, it is impossible to write out the returned object itself.

class GG 
{
public:
	GG(string name, int age) :name(name), age(age) {}

	//The initialization parameter list does not exist for ordinary functions
	void initData(string name, int age)
	{
		//Class name qualification helps the computer identify
		GG::name = name;
        //Or use the this pointer
		this->age = age;
	}
    //Output member data with this instead of object
	void print() 
	{    
		cout << this->name << " " << this->age << endl;
	}

    //Output the address pointed to by this pointer, which is the same as the address of the object
	void printThis() 
	{
		cout << this << endl;
	}

    //Use the this pointer to return the object
	GG& returnGG() 
	{
		return *this;
	}

	static void printStatic() 
	{
		GG gg("this", 19);
		cout << gg.name << "\t" << gg.age << endl;
	}
protected:
	string name;
	int age;
};

Tags: C C++ data structure

Posted on Wed, 01 Dec 2021 15:38:59 -0500 by irishpeck