From beginning to end - constructor and sector

zhaozj2021-02-17  52

From beginning to end

---- Construction and Design

Author: HolyFire

In the usual life, we will generally summarize some rules. Getting up in the morning will brush your teeth, and you will take a bath in the evening. These are practical. When you use a bottle to make a toner, open the cap and cover the bottle cap. This is a good habit. But some people are different. They are often lazy, one who often does not brush and don't wash your face, there will be a taste, and there will be a mess of life in a mess. These are all we don't want to see. Of course, we don't want the code to be chaotic in the program.

Using a uninited variable is a disaster, using an uninitialized pointer will cause crash. This is my advice. In the initialization of C , there will be no additional effects, which will not reduce efficiency. We have to develop a good habit and initialize it when an object is generated.

for

Object.init ();

Object.free ();

Such calls are not very difficult, to remember that he is not difficult, but no one can guarantee that he will never forget, worse

Object.init ();

Object.free ();

No pairing

Object.init ();

Object.free ();

Object.free ();

or

Object.init ();

Object.init ();

Object.free ();

What kind of results will be brought, no one knows, and such errors, the compiler will not report error. What a terrible mistake is, a programmer is most afraid of such a logical error, which may take a whole day to find such an error.

Let us see what is good.

An object is analyzed by time, usually three stages, birth, activity, death. What is the relevant to what we have to do, initialize, run, release. Very good, in contrast, we found that the time to initialize, death, if all this can operate with such a mechanism, we don't have to worry about it.

This mechanism is provided in C . Use him some agreement

Class Object {

PUBLIC:

Object (); // The function of the class is the same name, the function does not return value, called constructor

~ Object (); // Similarly, add a reflose sign before the constructor is called, called a destructor

}

The constructor will call when the object is generated.

The destructor will call when the object is destroyed.

The process and implementation method called by the compiler, as long as we remember the time they call, and their call is automated, do not require us to control.

#include

Using namespace std;

Class Object {

PUBLIC:

Object () {cout << "Object on!" << endl;}

~ Object () {cout << "Object off!" << endl;}

}

void main ()

{

Object O;

}

operation result

Object ON!

Object off!

Structure is implemented in functions and destructive functions

Now let's come to an example of an application

A string class, it needs to save the contents of the string, but it doesn't know the size of the string, then when designing this string class, the member variable of saving the string cannot be used in an array of fixed sizes, but can be indirectly Operate array pointer.

#include

#include

Using namespace std;

Class string {private:

CHAR * DATA;

PUBLIC:

String () {data = null;}

String (Char * STR)

{

COUT << "Copy String:" << str << end1

Data = New Char [Strlen (STR) 1];

Memcpy (DATA, STR, STRLEN (STR) 1);

}

Char * data () {return data;}

~ String ()

{

IF (DATA)

{

Cout << "free string:" << Data << endl;

DELETE DATA;

}

}

}

void main ()

{

{

String S ("abcd");

Cout << "Show string:" << s.data () << endl;

}

cin.get ();

}

Copy string: ABCD / / Execute String :: String (Char * STR) Constructor

Show string: ABCD

Free string: ABCD // Due to the object in {} is a temporary object, its life is over, so String :: ~ String () destructor is called

The operation of the application for memory and release memory is automatically completed, the purpose of constructor and the destructor is to initialize and release as a common type, thereby ensuring the package.

The above example has two constructor, so much deal, we have seen "the face ---- overload" knows that the heavy duty trick.

It should be noted that the constructor can have parameters and how to handle it in inheritance.

Class mystring: public string {

PUBLIC:

MyString (char * str): String (str) {}

}

MyString (Char * Str): String (STR)

Remember such a form, sending a function to your own parent class using such a writing format, which is a convention.

After the constructor, add one: indicating that it is an initialization sequence, saying that it is a sequence because it can initialize multiple member variables, call the parent class transfer parameters in the initialization sequence to ensure the order of the production, first generate The parent class is then a subclass. It is a good place to use initialization to improve efficiency.

String () {data = null;}

Can be rewritten

String (): data (null) {}

His role is to generate a member variable char * DATA to place his value as NULL. Thereby, less Data = NULL; this step.

Note that the structure and sequence here will have a sequential problem, which is to be called from the base class in the order of inheritance, and the order is just the opposite of the sequence. This is because the subclass may use the parent class's member variable in the constructor. If the parent class has not yet been created, then there is a problem, while the descent, if the parent class is analyzed, there will be such problem.

The destructor has a problem that can run correctly.

#include

Using namespace std;

Class one {

PUBLIC:

One () {cout << "One ON!" << endl;

~ One () {cout << "one OFF!" << endl;}

}

Class TWO: PUBLIC ONE {PUBLIC:

Two () {cout << "two on!" << endl;

~ Two () {cout << "Two OFF!" << endl;}

}

Class Three: Public Two {

PUBLIC:

Three () {cout << "Three on!" << endl;}

~ Three () {cout << "Three Off!" << endl;}

}

void main ()

{

Three three;

}

operation result

One ON!

TWO ON!

Three ON!

Three off!

TWO OFF!

One off!

correct

void main ()

{

Three * three = new three;

DELETE THREE;

}

operation result

One ON!

TWO ON!

Three ON!

Three off!

TWO OFF!

One off!

correct

void main ()

{

One * three = new three;

DELETE THREE;

}

operation result

One ON!

TWO ON!

Three ON!

One off!

Not good, TWO and Three are not running, how can this be, the original one * three pointed out that the pointer points to an ONE class object. How to get the correct result, if you can make the ONE class remember that the changes have been inherited.

correct! The virtual function, you can know in "Back to the Main ---- Dian Function", the virtual function has this feature, do not believe it.

Class one {

PUBLIC:

One () {cout << "One ON!" << endl;

Virtual ~ one () {cout << "one OFF!" << endl;}

}

void main ()

{

One * three = new three;

DELETE THREE;

}

operation result

One ON!

TWO ON!

Three ON!

Three off!

TWO OFF!

One off!

correct

This feature is very important. We must keep in mind that this method is "false argument", which is very extensive in the polymorphism, and is also an important technique written in multiplexed code.

The mechanism of action of constructors and sectations is automation, simplifying the complexity of programming. There is also that the resource allocated in a class constructor is trying to remember to release in the destructor in this class, of course, it is also allowed to release in advance, you can judge whether it is released in the destructor If it is not released. This is --- By starting to end, it indirectly describes the birth and death of an object (remember this is important, because I will use this characteristic control object life and death).

2001/8/23

Ding Ning

转载请注明原文地址:https://www.9cbs.com/read-28797.html

New Post(0)