6.2.2 Creating objects using classes
Once the declaration of a class is completed and its member functions are defined, the class is ready for use. A class that defines completion is a new type of data that we can use to define variables, that is, to create the objects described by this class, to represent various entities in the real world. For example, by completing the Declaration and definition of the teacher class, you can use it to create an object of the teacher class and use it to represent a specific teacher. The object of the class is created in a similar way to defining a variable, simply by defining the class as a data type, defining the object in the way we defined the variable, and the defined variable being the object of that class. The syntax format is as follows:
Class name Object name;
Where the class name is the name of the defined class, the object name is the name of the object to be defined, for example:
// define an object of type teacher Mrchen, on behalf of Mr. Chen Teacher Mrchen;
This gives a teacher class object Mrchen, which represents a specific teacher in the school. Once you have the object of the class, you can pass the "." Operators access the public members provided by this class, including reading and writing their public member variables and calling their public member functions to access their properties or to complete their actions. The syntax format is as follows:
The name of the object. Public member variable;
The name of the object. Public member function;
For example, to make the object you just defined Mrchen the "class" action, you can pass the "." Call it a member function that represents the class behavior:
// call the member function of the class to which the object belongs, indicating that the teacher started the class Mrchen.givelesson ();
In this way, the object executes the Givelesson () member function defined in the teacher class, completing the specific action of the class.
In addition to using the object directly, with the normal data type can use the corresponding type of pointer to access the data it points to, for its own definition of the class, we can also treat it as a data type to define a pointer to a specific object, and then through the pointer to access the members of the object. For example:
// defines a pointer pmrchen that can point to an teacher type object, initialized to a null pointer teacher* pmrchen = nullptr; // Use the "&" operator to get the address of the Mrchen object assigned to the pointer Pmrchen, // That is, pointing the Pmrchen pointer to the Mrchen object pmrchen = &MrChen;
Here, we first treat the teacher class as a data type, use the same form as the normal data type definition pointer, define a pointer pmrchen that can point to the teacher type object, and then get the address of the Mrchen object and assign it to the pointer through the "&" operator. This points the pointer to the Mrchen object.
In addition to using the "&" operator to get the address of an existing object and assigning a pointer to an object with this address, you can also use the "new" keyword to directly create an object and return the address of the object, and then use this address to assign a value to the pointer, You can also create a new object and point the pointer to the new object. For example:
// to create a new teacher object // and let the Pmrchen pointer point to the new object New Teacher ();
Here, the "new" keyword is responsible for completing the creation of the teacher object, returning the address of the object, and then assigning the returned object address to the Pmrchen pointer, which completes both the creation of the object and the assignment of the pointer.
With pointers to objects, you can take advantage of the "-and" operator (is this operator much like a pin?). ) to access the members of the object through a pointer. For example:
// access the object's member Pmrchen->givelesson () through pointers;
It is important to note that, unlike normal variables, objects created with the "new" keyword cannot be automatically destroyed at the end of their life cycle, so we must use the "delete" keyword to artificially destroy the object when the object is used, freeing up the memory it occupies. For example:
// destroys the object pointed to by the pointer = nullptr; // after the object is destroyed, it becomes a null pointer again
The "delete" keyword first pmrchen the teacher object pointed to by the teacher class, and then releases the memory that the object occupies, and the entire object is destroyed. When the object is destroyed, the original pointer to the object is a "wild pointer" to an invalid address, in order to prevent the "wild pointer" is mistakenly used again, after destroying the object with the Delete keyword, we usually assign the pointer to nullptr, making it a null pointer, Avoid its re-use.
Best practice: No need to test whether the pointer is nullptr after "new" or "delete"
Many experienced C + + programmers will emphasize that in order to increase the robustness of the code, we should first determine whether the pointer is nullptr before using it, and then make sure it is valid before using it. It should be said that such checks are necessary when using pointers to access the members of a class. If you check before "new" is created and the "delete" destroys the object, it is completely superfluous.
On the one hand, when creating a new object using "new", if the system cannot allocate enough memory to create a new object to cause the object to fail, a Std::bad_alloc exception is thrown, and the "new" Operation never returns NULLPTR. On the other hand, the C + + language also guarantees that if the pointer P is a nullptr, then "delete P" does nothing and naturally there will be no error. Therefore, there is no need to check the validity of pointers before using "new" to create objects and the "delete" keyword before destroying them, so it is good to use them directly.
// Creating Objects New Teacher (); // use pointer p directly to access the object ... // destroying Objects delete p; // after destroying the object, you need to assign the pointer to nullptr, avoiding the appearance of the "Wild pointer" p = nullptr;
6.2. Birth and death of 31 objects: constructors and destructors
In the real world, every thing has its life cycle, and at some point it will die at another time. The program is a reflection of the real world, where the object represents the real world of all kinds of things, nature will also have a life cycle, will be created and destroyed. The creation and destruction of an object is often a very important moment in his life, and many complex things need to be dealt with. For example, when you create an object, you need to do a lot of initialization work, set the initial value of some properties, and in the destruction of the object, it is necessary to do some cleanup work, the most important thing is to release the application resources, the open file closed, as if a person died, should be the money back, clean walk. To accomplish both the life and death of the object, the classes in C + + specialize in providing two special functions-constructors (Constructor) and Destructors (destructor), which are special in that they are automatically invoked when objects are created and destroyed. To handle the complex work of object creation and destruction, respectively.
Since the constructor is called automatically when the object is created, we can use it to do a lot of things that are inconvenient to do after the object is created, such as the ability to initialize certain properties of an object in the constructor, so that once the object is created there is a reasonable initial value. This is like the human gender is determined in the womb, once born has a clear gender. C + + stipulates that each class must have a constructor, and if a class does not explicitly declare a constructor, the compiler will also produce a default constructor for it, except that the default constructor has no parameters and does nothing extra. And if we want to do some special tasks in the constructor, we need to add a constructor for our class. You can add constructors to a class in the following ways:
class class Name {public: class name (argument list) { // Construction of class, completion of initialization work }};
Because the constructor has a particularity, its declaration is also very special.
First, in most cases, the access level of the constructor should be public, because the constructor needs to be called outside to create the object. Other access levels are used only for a few special purposes. For example, in the single-piece mode described in section 6.4.4, we set the constructor to private, preventing the outside world from creating objects directly from the constructor.
The second is the return value type, the constructor just completes the object creation, does not need to return the data, naturally also does not matter the return value type.
followed by the function name, the constructor must have the same name as the class, that is, the name of the class as the constructor.
Finally, the parameter list, like the normal function, in the constructor we can also have a parameter list, the use of these parameters to pass in the data to complete the initialization of the object, so that the different parameters can be created to achieve a differentiated object. Depending on the parameter list, a class can have multiple constructors to accommodate different constructs.
The teacher class above has no explicit (so-called explicit, relative implicitly, which usually refers to the things we produce with code that explicitly expresses our intentions. For example, a user-defined constructor. Implicit is that the user is not explicitly defined by the code, and the compiler automatically generates things for it. For example, a default constructor) declares a constructor, instead uses the default constructor generated by the compiler, so that the objects it creates are identical, and all newly created object M_strname member variables are the fixed initial values given in the class declaration. In other words, all "teachers" are the same "name", which is obviously unreasonable. Rewrite the teacher class below, adding a constructor with a string parameter to it to make it possible to properly initialize member variables by constructors when creating objects, creating differentiated objects:
classteacher{ Public://constructor Function//parameter represents the name of the Teacher class objectTeacher (stringStrName)//Constructors with parameters { //use parameters to assign values to member variables for initializationM_strname =StrName; }; voidGivelesson ();//Preparationprotected: stringM_strname ="Chenliangqiao";//the initial value in the class declaration//namePrivate:};
You can now write the arguments in parentheses after the object name when you define the object, which invokes the constructor teacher (string strName) with the argument, giving the object its Name property.
// using parameters, create an object named "Wanggang" Teacher Mrwang ("wanggang");
In the above code, we use the string "Wanggang" as the argument for the constructor, and it invokes the teacher (string strName) constructor in the teacher class that requires a string type argument to complete the creation of the object. In the constructor, this parameter value is assigned to the M_STRNAME member variable of the class in place of its fixed initial value "Chenliangqiao" given in the class declaration. When the object is created, the parameter value "Wanggang" becomes the value of the name attribute of the Mrwang object, so that we create a teacher object with a specific "name" through the parameters, and the teacher can finally have its own name.
In the constructor, in addition to using the "=" operator to assign a value to a member variable of an object to complete initialization, you can also use the ":" Symbol to initiate the initialization of a property list after the constructor, directly using the constructor's arguments or other reasonable initial values to initialize the member variable. The syntax format is as follows:
class class Name {public: // constructor class name with initialization attribute list (parameter list) : Member variable 1 (initial value 1) , member variable 2 (initial value 2) ... // Initializing a property list { }// Other declarations and definitions of class };
Before entering the constructor execution, the system completes the creation of the member variable and assigns it using the initial values in parentheses thereafter. These initial values can be parameters of a constructor or a reasonable initial value for a member variable. If a class has multiple member variables that need to be initialized in this way, then multiple variables can be separated by commas. For example, you can use the Initialization property list to overwrite the constructor of the teacher class with:
class teacher{ public : // Teacher (string StrName // Initialize the list of properties, use the constructor's parameters strname create and initialize M_ StrName : M_strname (strName) { / / No need to assign a value to M_strname protected : string M_strname;};
Using the constructor that initializes the property list, the member variable m_strname of the teacher class is created directly with the parameter strname and initialized, eliminating the extra work of assigning a value to m_strname using "=". The efficiency of object construction can be improved to some extent. In addition, some member variables must be created with initial values, such as some member variables decorated with the Const keyword, in which case it is necessary to initialize the member variable with the initialization of the attribute list. Therefore, it is best to use the constructor's initialization property list to complete the initialization of the class's member variables, where possible.
It is important to note that if a class already has an explicitly defined constructor, the compiler will no longer generate a default constructor for it. For example, after the teacher class has an explicitly declared constructor, if you still want to define the object as follows, a compilation error will occur.
// attempting to call the default constructor to create a teacher without a name Teacher Mrunknown;
The compiler will then prompt for an error because the class already has no default constructor, and the only constructor needs to give a parameter, and the form of the created object will cause a compilation error because the appropriate constructor cannot be found. Therefore, when implementing a class, it is generally possible to explicitly write out the default constructor, and to add a constructor with parameters as needed to accomplish some special construction tasks.
In C + +, depending on the initial conditions, we often need to create an object in a variety of ways, so a class often has multiple constructors of different parameters, each of which is responsible for creating objects in different ways. And in these constructors, there are often some work that everyone needs to do, and one of the constructors ' work is likely to be part of the work that another constructor needs to do. For example, the teacher class has two constructors, one is a default constructor without parameters, it gives the M_nage member variable of the teacher Class A default value of 28, and the other is a parameter, it first needs to determine whether the parameter is within a reasonable range, and then assign a reasonable parameter to the M_ NAge. Both of these constructors need to be done to assign a value to the m_nage, and the work of the first constructor can be done with the second constructor given parameter 28, so that the work of the second constructor becomes part of the work to be done by the first constructor. To avoid duplication of code, we only need to implement these common functions in a particular constructor, and in the constructors that require these common functions, call this particular constructor directly. This approach is called a delegate call constructor (delegating constructors). For example:
classteacher{ Public: //Constructors with parametersTeacher (intx) {//Determine whether the parameter is reasonable or not if(0< x && x <= -) M_nage=x; Elsecout<<"wrong age parameter"<<Endl; } //constructor Teacher () delegate call constructor teacher (int x)//Here we mistakenly call the year of birth as the age parameter delegate calls the constructor teacher (int x),//the function of validation and assignment of parameter legitimacy is realized directly.Teacher (): Teacher (1982){ //complete the unique creation work}// ...Private: intM_nage;//Age};
Here, we add a colon ":" After the constructor, and then follow the invocation form of another constructor, implementing a constructor delegate call to another constructor. Calling another constructor in one constructor, handing part of the work to another constructor to complete, is the delegate's meaning. Different constructors are responsible for dealing with their own specific situations, and the most basic common construction work is delegated to some basic constructors to accomplish the task of division and collaboration.
When an object created using a defined variable is used to leave its scope, the object is automatically destroyed. For objects created with the new keyword, you need to actively destroy the object by using the Delete keyword when you are finished with it. Either way, the object needs to be destroyed after it has been used, which is to do the necessary cleanup, such as releasing the requested memory, closing the open file, and so on.
With the creation of objects more complex, requires specialized constructors to complete the same, the destruction of objects is more complex, the same needs a special destructor to complete. There are many similarities between the special functions that are responsible for object creation and destruction in the same class. The first is that they are automatically called, except when the object is created and the other is when the object is destroyed. Second, the function names of the two are made up of the class name, except that the destructor name has a "~" symbol in front of the class name to distinguish it from the constructor name. Second, both have no return value, both of which are public access levels. Finally, if it is not necessary, both can be omitted from the class. If the constructors and destructors are not explicitly declared in the class, the compiler automatically generates default functions for them. The only difference between the two is that the constructor can have many forms of arguments, and the destructor does not accept any arguments. Here are some cleanup tasks for the teacher class plus destructors to replace the default destructors:
classteacher{ Public://Public access Level//... ..// Destructors//precede the class name with "~" to form the destructor number name~teacher ()//do not accept any parameters { //Perform cleanup workcout<<"Spring Silkworm to the dead silk side, wax torch into Ashes tears began to dry"<<Endl; }; //... ..};
Because the teacher class does not require additional cleanup work, we do not define any operations here, just output a piece of information representing the end of the teacher class object. In general, things that need to be done automatically before the object is destroyed are handled in a destructor. For example, the memory resource requested when the object was created can no longer be occupied after the object is destroyed, and it needs to be properly released in the destructor and returned to the operating system. Just like a reputable person, before leaving the world, to pay off the money owed to others, clean away.
Hello, C + + (33) object life and death two boundless 6.2.31 Objects of birth and death: constructors and destructors