Core Programming for C++ Notes

4. Classes and Objects

2. Initialization and cleaning of objects

  • Computers, mobile phones and other electronic products have "factory settings". We can delete some private data for security
  • C++ Object Oriented comes from life, and each object also has the option to clean up data with initial settings and object destruction

1. Constructors and Destructors

1. Concepts

  • Constructor: assigns values to the object's member properties (i.e. the initializer) when the object is created, and is called automatically by the compiler
  • Destructor: The system calls automatically to do some cleanup before the object is undone
  • Constructors and destructors are used to initialize and clean up objects (they are called automatically by the compiler), which is provided automatically by the compiler if they are not provided in programming, but is empty by the compiler.

2. Syntax of constructor: class name (){}

  • Constructor does not return a value nor write void
  • The function name is the same as the class name
  • Constructors can have parameters, so overloads can occur
  • A program automatically calls a constructor when it calls an object, without having to call it manually, and only once
  • #include<iostream>
    using namespace std;
    
    class person
    {
    public:
    //Constructor Class Name (){}
    	person()//There is no need to add viod, there can be parameters or no parameters, and the function and class names are the same (all people)
    	{
    		cout << "Calls to constructors" << endl;//If you don't write this, the compiler will write it for you,
    		                                 //It's just that the compiler writes nothing, a black screen, nothing
    		                                 //And when you write, the screen shows what you write
    	}
    };
    
    void test01()
    {
    	person p;
    }
    int main()
    {
    	test01();//A value appears once on the screen, indicating that the value calls the constructor once
    	system("pause");
    	return 0;
    }

3. Destructor syntax: class name (){}

  • Constructor does not return a value nor write void
  • The function name is the same as the class name, preceded by a symbol~
  • Constructors can have no parameters, so no overload can occur
  • A program automatically calls a constructor when it calls an object, without having to call it manually, and only once
  • #include<iostream>
    using namespace std;
    
    //Constructor
    class person
    {
    public:
    	person()//There is no need to add viod, there can be parameters or no parameters
    	{
    		cout << "Calls to constructors" << endl;//If you don't write this, the compiler will write it for you,
    		                                 //It's just that the compiler writes nothing, a black screen, nothing
    		                                 //And when you write, the screen shows what you write
    	}
    	//Destructor: ~Class name (){}
    	~person()//No viod, no parameters
    	{
    		cout << "Call to destructor" << endl;
    	}
    };
    
    void test01()
    {
    	person p;//On the stack, when test01 finishes executing, release the object
    }
    int main()
    {
    	test01();//A value appears once on the screen, indicating that the value calls the constructor once
    	system("pause");
    	return 0;
    }

Classification and invocation of constructors

1. Two classifications

  • Classify by parameter: with and without parameters (default construction)
  • Classify by type: ordinary constructs and copy constructs (meaning copy)

2.Three calling functions

  • Bracket hair
  • Display method
  • Implicit Conversion

3. Note:

  • Do not parenthesize when calling the default constructor (because the compiler will think this is a declaration of the function)

  • Do not use copy functions to initialize anonymous objects

  • #include<iostream>
    using namespace std;
    
    
    class person
    {
    public:
    	//Constructor
    	person()
    	{
    		cout << "Calls to construct parameterless functions" << endl;
    	}
    	person(int a)
    	{
    		age = a;
    		cout << "Construct calls to parameterized functions" << endl;
    	}
    	//copy constructor
    	person(const person &p)//To copy by reference to a constant
    	{
    		age = p.age;//Copy all attributes of the incoming person onto the current object
    		cout << "Call to copy constructor" << endl;
    	}
    	~person()
    	{
    		cout << "Call to destructor" << endl;
    	}
    	int age;
    };
    
    //call
    void test01()
    {
    	//bracketing
    	cout << "Bracket calls:" << endl;
    	person p1;//Default function construction call
    	person p2(10);//Calls to parameterized functions
    	person p3(p2);//Calls to copy functions
    
    	cout << "p2 Age:" << p2.age << endl;//The upper afferent is 10, so the age of p2 is 10
    	cout << "p3 Age:" << p3.age << endl;//The age of p2 is copied into p3, so P3 is also 10
    
    	//Display method
    	cout << "Display method calls:" << endl;
    	person p4;//Default Construction
    	person p5 = person(10);//Parameterized function call
    	person p6 = person(p5);//Copy function call
    
    	person(10);//Anonymous object feature: the system will recycle anonymous objects immediately after the current line is executed
    	cout << "aaa" << endl;//Anonymous object is released before executing this output
    	     //Copy function initializes anonymous objects
    	//Person(p5);//The compiler thinks person(p5)=person p5, and the compiler will error
    	
    	cout << "Implicit Conversion" << endl;
    	//Implicit Conversion
    	person p7 = 10;//Equivalent to person p7 =person(10) with parametric construction
    	person p8 = p7;//copy construction
    }
    int main()
    {
    	test01();
    	system("pause");
    	return 0; 
    }

3. Timing for calling copy functions

Use cases

  • Initialize a new object with an already created object
  • How values are passed to function parameters
  • Return local objects as values
#include<iostream>
using namespace std;


class person
{
public:
	person()
	{
		cout << "Call to default constructor" << endl;
	}
	person(int age)//Initialize age
	{
		cout << "Calls to parametric constructors" << endl;
		m_age = age;
	}
	person(const person &p)//copying functions
	{
		cout << "Calls to copy functions" << endl;
		m_age = p.m_age;
	}
	~person()
	{
		cout << "Call to destructor" << endl;
	}
	int m_age;
};

//Initialize an object with an object that has been created
void test01()
{
	person p1(20);
	person p2(p1);
}

//Pass values to functions in the form of values
void dowork(person p)
{

}

void test02()
{
	person p;
	dowork(p);
}

//Return local object by value
person dowork03()
{
	person p3;//Call default function
	cout << (int*)&p3 << endl;
	return p3;//Call copy function
	//Return a new object based on p3 copy
}
void test03()
{
	person p = dowork03();
	cout << (int*)&p << endl;
}
int main()
{
	cout << "01" << endl;
	test01();
	cout << "02" << endl;
	test02();
	cout << "03" << endl;
	test03();
	system("pause");
	return 0; 
}

4. Constructor Call Rules

1. By default, c++ programming adds at least three functions to a class

  • Default constructor (parameterless body is empty)
  • Default destructor (parameterless body is empty)
  • Default copy function to copy object properties

2. Constructor Call Rules

  • If the user defines a parametric constructor, c++ is not the default parametric constructor, but improves the parametric destructor
  • c++ does not provide any other constructors if a user-defined copy constructor

5. Deep and Shallow Copies

  • Shallow copy: a simple assignment copy operation
  • Deep copy: reapply space in the heap area for copy operation
  • Summary: If a property has a heap area open, be sure to provide the copy function yourself to prevent the problem of shallow copy

1. Shallow copy problem: duplicate heap release

#include<iostream>
using namespace std;


class person
{
public:
	person()
	{
		cout << "Call to default constructor" << endl;
	}
	person(int age,int height)//Initialize age
	{
		cout << "Calls to parametric constructors" << endl;
		m_age = age;
		m_height=new int(height);//Objects opened by heap area include programmer creation and programmer release
	}
	
	~person()
	{
		//Destruction code: Release data opened by heap area
		if (m_height != NULL)
		{
			delete m_height;
			m_height = NULL;
		}
		cout << "Call to destructor" << endl;
	}
	int m_age;
	int* m_height;//height
};

//Initialize an object with an object that has been created
void test01()
{
	person p1(20,163);
	cout << "p1 Age is:" << p1.m_age<<"p1 Height is:" <<*p1.m_height<< endl;
	person p2(p1);
	cout << "p2 Age is:" << p2.m_age << "p2 Height is:" << *p2.m_height << endl;
}


int main()
{
	cout << "01" << endl;
	test01();
	system("pause");
	return 0; 
}

2. Shallow copy problem solving: using deep copy to solve

  • Implement the copy constructor yourself to solve the problem of shallow copy
  • deep copy
  • Re-open a heap area, that is, where p1 originally pointed to one heap area and p2 now pointed to another
​person(const person &p)//copying functions
	{
		cout << "Calls to copy functions" << endl;
		m_age = p.m_age;
		//m_height = height; //Code for compiler's default copy function
		//Deep copy operation
		m_height = new int(*p.m_height);
	}

6. Initialization list

  • Role: Used to initialize properties
  • Syntax: Constructor (): Attribute 1 (value 1), Attribute 2 (value 2).... {}
#include<iostream>
using namespace std;

class person
{
public:
	//Traditional Initialization Operations
	/*person(int a, int b, int c)
	{
		m_a = a;
		m_b = b;
		m_c = c;
	}*/
	//Initialize List Initial Properties
	person(int a,int b,int c) :m_a(a), m_b(b), m_c(c)
	{
	
	}
	int m_a;
	int m_b;
	int m_c;
};

void test01()
{
	//person p(10, 20, 30);
	person p(10,20,30);
	cout << "m_a:" << p.m_a << endl;
	cout << "m_b:" << p.m_b << endl; 
	cout << "m_b:" << p.m_c << endl;
}

int main()
{
	test01();
	system("pause");
	return 0; 
}

7. Class object is the most class member

  • Object member: A member of a class is an object of another class
  • class A
    {
    
    }
    class B
    {
      A a;//Class B has object A as a member, A is called an object member
    }
  • When objects of other classes are members of this class, construct other classes first, then construct themselves; the order of destructions is opposite to that of construction.
  • #include<iostream>
    using namespace std;
    #include<string>
    
    class phone
    {
    public:
    	phone(string pname)
    	{
    		cout << "phone constructor call" << endl;
    		p_name = pname;
    	}
    	~phone()
    	{
    		cout << "phone Destructor Call" << endl;
    		
    	}
    	string p_name;
    	
    };
    
    class person
    {
    public:
    	//Phone p_name=p name implicit conversion
    	person(string name, string pname) :m_name(name), m_phone(pname)
    	{
    		cout << "person constructor call" << endl;
    	}
    	~person() 
    	{
    		cout << "person Destructor Call" << endl;
    	}
    	string m_name;
    	phone  m_phone;
    };
    
    //When the objects of other classes are members of this class, construct the other classes first, then construct themselves.
    //The order of destructions is opposite to that of construction
    void test01()
    {
    	person p("Zhang San", "Apple MAX");
    	cout << p.m_name << "Hold:" << p.m_phone.p_name << endl;
    }
    int main()
    {
    	test01();
    	system("pause");
    	return 0; 
    }

     

9. Static members

A static member is a member variable or function preceded by a "static"

1. Static member variables

  • All share the same data
  • Assignment during compilation phase
  • Intra-class declaration, out-of-class initialization

2. Static member functions

  • All objects share a function
  • Static member functions can only access static member variables

Tags: C++

Posted on Sat, 09 Oct 2021 12:03:27 -0400 by $0.05$