Let's first take a look at the problems left last time. "Why (lasting is three, this time is six, can you explain?" What should I do? "The reasons, I think you understand, I only do simple repeat :). Code segment:
// Bool Issameman IF (Issameman (Lucy, Lily) // (1) {std :: cout << "/ n they is the same one./n";} else std :: Cout << "/ n no, they're not the same one./n";
} (1) The sentence is passed to two objects (Lucy, Lily), according to the definition of the Human class, the system attempts to copy their resources to One and Another, but there is no doubt that a shallow copy issue. When the objects ONE and ANOTHER are destructed, the problem is shown. As for why it is six anomalies, huh, or you answer? It is easy to solve the reason. We need a copy constructor to complete the work of this resource copy, as follows:
IF add ... in class human (public):
Human (Human & Human): ID (human.getid ()) {name = new name (human.getname () -> getname ());}
OK, And you get:
There is no problem with the isy it. .Press any key to contact.
This time, let's take a look at the initialization problem in the combination and inheritance, and finally explain the place where the object array initialization needs to be careful. Mainly inherited. I want to clarify some ideas and emphasize some ideas. Of course, if you have a controversial place, you are welcome to point me. Thank you. Everyone knows that combination and inheritance are very important coupling methods. Examples of typical combination and inheritance, as follows:
Class Point {Int x, y; // ... public: // ...};
Class Shape {protected: POINT P0; / / Combination // ... public: shape (int x, int y); shape (point & point); // ...};
Class Window: Public Shape {// Inherited int width, height; // ... public: window (int _x, int _y, int _w, int _h); // ...}; in initialization, it may be like this of:
Window :: Window (int _x, int _y, int _w, int _h): shape (_x, _y), width (_w), height (_h) {} // (1) combination and inheritance initialization, if it is us I will do this, and the time initialized can only have this one, (1) after the colon. This is the syntax of C , there is nothing to say. However, I think, now, some know, I need to have emphasized. First, the objects in C must be initialized when creating. In general, we have to do this work; but if you don't give your own constructor, the system will give a default constructor and call it (do you know what it will do?). Initialization must be guaranteed. Second, in the initialization of complex classes (combined inheritance), the constructor is adjusted to have a fixed order. The general C textbook is very detailed, I will not say much. But interesting is that in complex classes, what happens if the default system is initialized? If all the parent classes do not write constructor, the class of member objects has no write constructor, but there is no constant member and reference member, and a series of initialization work is executed in the original order, still no initialization? This issue may have no practical meaning, but it is very meaningful to understand the initialization of understanding, I think.
We initialize the inheritance to an example, step by step.
Let's take a look, if you don't write the constructor, what is the system will do. Class definition. First, Shape is an abstract base class (interface). I didn't write any constructor to let the system come.
//shape.h#pragma overce
Class Shape {Protected: INT X, Y; PUBLIC: Virtual ~ Shape (Void); Virtual Void Setxy (INT _X, INT _Y) = 0;}; // Shape.cpp # incrude "Shape.h" #using
Shape :: ~ Shape (void) {} The following is a subclass implementation of the Shape class, Window. In order to compare the test, it has two constructor, one is no parameters, do not do anything, of course, we can assume that it doesn't know that it will call the parent class shape constructor. The other is a normal constructor, but from the parent class
The inherited members are not initialized (see how the system is done). //Window.h#pragma once # include "shape.h"
Class window: public shape {int width, height; public: window (void); Window (int _x, int _y, int _w, int _h); virtual ~ window (virtual void setxy); Virtual Void Setxy (int _x, int _y) ;
Void test (void);}; // window.cpp # include
Void window :: setxy (int _x, int _y) {x = _x; y = _y;} // void window :: test (void) {std :: cout << "x =" << x << ", Y = "<< Y <<", width = "<< width <<", height = << Height << "/ n / n";}
This is a common test file: //fmain.cpp#include
Window Win (10, 10, 50, 50); std :: cout << "TEST: WIN: / N"; win.test ();
Execute, the result is as follows:
Test: win2: x = 1243328, y = 1243040, width = 1303984, Height = 1243296
Test: win: x = 1243040, y = 1, width = 50, Height = 50
Press any key to continche
Win2 call is a constructor 1, Win call is a constructor 2. All members of Win2 seem to be randomized. In Win, only Width and Height have achieved expected results, X and Y and Win2 have no difference! Interim remember, this is the result of not writing constructor.
We now add constructor to the Shape class, there are two versions, which work with the constructor of the Window class. As follows: //shape.h#pragma overce
Class Shape {Protected: INT X, Y; Public: Shape (Void); Shape (INT _X, INT _Y); Virtual ~ Shape (Void); Virtual Void Setxy (INT _X, INT _Y) = 0;}; // Shape.cpp # include "shape.h" #using
Shape :: ~ shape (void) {}
The constructor of the WINDOW class is correctly corrected as follows: // Constructor 1Window :: Window: Shape () {} // Constructor 2Window :: Window (int _x, int _y, int _w, int _h): Shape _X, _y) {width = _w; height = _h;}
The test file code is unchanged. Execute, the result is as follows:
Test: win2: x = 1243328, y = 1243040, width = 1303984, height = 1243296test: win: x = 10, y = 10, width = 50, Height = 50
Press Any Key to Continue Win2 has not been changed, but Win initialization is what we want! This shows what? If you don't understand, you can look back and look back.
The default initialization of the system, even if the value it gives is the value of the memory address at that time (unpredictable), but it is still initialization!
Speaking of the default initialization, pay special attention when you want to create an object array, if you don't have a save constructor, the object array is unable to create, because there is no suitable constructor to be called! (If you can't initialize, the compiler is made wrong)
The constructor of the Shape and the WINDOW class is correctly corrected as follows:
// Constructor 1:
Shape :: Shape (void) {
X = 0; y = 0;} // Constructor 1Window :: Window (void): shape () {
Width = 0; height = 0;} The code in the main function is changed to:
WINDOW WIN [5]; for (int i = 0; i <5; i ) {std :: cout << "test:" << i << ": / n"; win [i] .test (); }
The result is: Test: 0: x = 0, y = 0, width = 0, Height = 0
Test: 1: x = 0, y = 0, width = 0, Height = 0
Test: 2: x = 0, y = 0, width = 0, Height = 0
Test: 3: x = 0, y = 0, width = 0, Height = 0
Test: 4: x = 0, y = 0, width = 0, Height = 0
Press any key to continche
However, you take the constructor of the Shape class out (not only deleting the default constructor), and then compile when compiling the same test file:
Window.cpp (5): Error C2512: "Shape": There is no suitable default constructor available
In short, I think this is a must: initialization work must be completed. In any case, the system completes the mechanism of initialization work is constant (the sequence of constructor calls), the system is not lazy :). We need to design a good initialization process.
This legacy problem is that all of these issues will happen in the combination? When the object array is initialized, if we want the initialization status of each object, how should it be? If you don't feel clear enough, I hope you can write the code to test, follow the results :).