The first time to record technology-related knowledge, I believe that the future will be able to see their progress!
I've been busy looking for a job because I have to deal with various written tests. So do a few exercises, do not know how to practice a scare jump.
Discover that your basic knowledge of C + + is almost forgotten. Suddenly regrets to copy and paste the results for many years ...
1. About the construction and destruction sequence:
Include "StdAfx.h"
#include <iostream>
using namespace Std;
Class One
{
Public
One () {cout<< " One";}
~One () {cout<< "~ One";}
};
Class A
{
Public
Both (Int J) {cout<< " both";}
~ Both () {cout<< "~ ";}
};
Class Three
{
Public
three () {cout<< "three ";}
Virtual ~three() {cout<< "~three ";}
};
Class Four:public three
{
Public
Four (Int J)
{
cout<< " four";
PB = new (j);
}
~ Four ()
{
Delete PB;
cout<< "~ four";
}
Private
Both *PB;
one A;
};
int _tmain (int argc, _tchar* argv[])
{
three* pc = new Four (1);
Delete pc;
return 0;
}
Three one four ~two ~four ~one ~three
This example is mainly about the function of the base class virtual destructor.
As you can see from the answer, the order of construction is the base class, the member object of the subclass, and the subclass.
If there is no PB = new Two (j) This sentence, there is only a second *PB; The constructor is not called at all (Suddenly you feel silly, This is the obvious thing but hesitated ... )
If class three does not declare a virtual destructor, no other destructors are called when the Delete PC statement is called.
Similarly if the statement in the _tmain function is changed to four* PC = new Four (1)
It doesn't matter if the class three is a virtual destructor, and delete will call the other class's destructor in order.
To summarize, the virtual destructors in the base class are mostly used to protect against the on-going transformation objects (think so).
Delete on a transform object, if the destructor of the base class at this time is a virtual function, the destructor of the other class associated with the subclass object is called sequentially.
If the destructor of the base class is not a virtual function at this time, only the destructor of the base class is called, which leaves a hidden danger to the memory leak.
2. about sizeof:
#include <iostream>
Class A
{
Public
A () {}
A (int a,unsigned int b): M_a (a), M_b (b), M_c () {}
Public
int m_a;
unsigned int m_b;
A * m_c;
};
Class B:public A
{
Public
B () {}
Public
static int m_d;
};
int _tmain (int argc, _tchar* argv[])
{
* A;
b b;
Std::cout<<sizeof (A) << "";
Std::cout<<sizeof (b) << "";
Std::cout<<sizeof (a) << "";
A = new b[2];
Std::cout<<sizeof (a) << "";
return 0;
}
The answer is 12 12 4 4
Always thought that the size of unsigned int is 2, today tried a bit originally was 4.
Furthermore, because A is a pointer, everything that a points to is 4. Don't be fooled by a = new b[2].
That day also encountered a similar problem, if a simple empty class what variables are not, this empty class of sizeof is 1 (specifically why 1 is not clear. ~ ~ Old Chinese Medicine style, take to use it
Furthermore, if there is a static parameter in the class, the static parameter is not space-saving, it is estimated that the storage of the static parameter is no longer within the reason of the class. Initialization is no longer in class.
3. Still a constructor
#include <iostream>
Class A
{
Public
A (int n=0): m_i (n) {std::cout<<m_i;}
Protected
int m_i;
};
Class B:public A
{
Public
B (int n): M_j (n), M_a (--m_j), M_b () {std::cout<<m_j;}
Private
int m_j;
A M_a;
A M_b;
Static A M_c;
};
int _tmain (int argc, _tchar* argv[])
{
b b (2);
std::cout<<std::endl;
return 0;
}
The answer is 0101.
This problem is very strange is also very good a problem, at first think the answer is certainly wrong, a run answer really is true ...
This problem is mainly to examine the construction order of the class and the initialization order of the member variables.
The first output 0 is because the constructor of the base class is called first, and the default parameter in the base class is 0.
The second output 1 is because a m_a is executed, when a's constructor is called,
By B's initialization list B (int n): M_j (n), M_a (--m_j), you can see that the first value of the M_j assignment is 2,
Then m_a (--m_j) passes 1 to the constructor of a, so it outputs 1.
The third output 0 is a m_b, and the constructor of a is called without an incoming parameter, so the default parameter 0 is used.
The fourth output 1 is the last to invoke the constructor of B, although 2 is passed in, but the previous --m_j makes the m_j value 1.
Knowledge Summary after C + + coding Practice