C ++ Object Construction and Analysis, and memory Layout

Source: Internet
Author: User

This article mainly discusses the object construction sequence and memory layout. The main reference source is the 14th sequence in the predictional C ++ Style Chinese edition! Order! According to the following code excerpt, some debugging information is added to the Code. [Cpp] # include <map> struct classcomp {bool operator () (const _ int64 & lhs, const _ int64 & rhs) const {return lhs <rhs ;}}; std: multimap <__ int64, std: string, classcomp> m_Construtor; class B1 {public: B1 () {std :: cout <"Constructor B1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B1");} virtual ~ B1 () {std: cout <"Destructor B1" <this <'\ n' ;}}; class V1: public B1 {public: V1 () {std: cout <"Constructor V1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor V1");} virtual ~ V1 () {std: cout <"Destructor V1" <this <'\ n' ;}}; class D1: virtual public V1 {public: D1 () {std: cout <"Constructor D1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor D1");} virtual ~ D1 () {std: cout <"Destructor D1" <this <'\ n' ;}}; class B2 {public: B2 () {std :: cout <"Constructor B2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B2");} virtual ~ B2 () {std: cout <"Destructor B2" <this <'\ n' ;}}; class B3 {public: B3 () {std :: cout <"Constructor B3" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B3");} virtual ~ B3 () {std: cout <"Destructor B3" <this <'\ n' ;}}; class V2: public B1, public B2 {public: v2 () {std: cout <"Constructor V2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor V2");} virtual ~ V2 () {std: cout <"Destructor V2" <this <'\ n' ;}}; class D2: public B3, virtual public V2 {public: d2 () {std: cout <"Constructor D2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor D2");} virtual ~ D2 () {std: cout <"Destructor D2" <this <'\ n' ;}}; class M1 {public: M1 () {std :: cout <"Constructor M1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor M1");} virtual ~ M1 () {std: cout <"Destructor M1" <this <'\ n' ;}}; class M2 {public: M2 () {std :: cout <"Constructor M2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor M2");} virtual ~ M2 () {std: cout <"Destructor M2" <this <'\ n' ;}}; class X: public D1, public D2 {public: X () {std: cout <"Constructor X" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor X");} virtual ~ X () {std: cout <"Destructor X" <this <'\ n';} private: M1 _ m1; M2 _ m2 ;}; int _ tmain (int argc, _ TCHAR * argv []) {// B B; int I; X * pX = new X; std :: cout <"------------------------------------------" <'\ n'; cout. setf (ios: showbase | ios: uppercase); // you can specify the uppercase characters in the base indicator output and the numbers to output std: multimap <__ int64, std: string, classcomp >:: iterator iter; for (iter = m_Construtor.begin (); iter! = M_Construtor.end (); ++ iter) // traverses {cout <std: hex <(* iter ). first <"" <(* iter ). second <endl;} std: cout <"------------------------------------------" <'\ n'; delete pX; pX = NULL; std: cin> I; return 0;} the running result of the above program is: Constructor B1 005F7F94Constructor V1 005F7F94Constructor B1 005F7F98Constructor B2 1_v2 1_d1 1_b3 1_d2 005F7F8 0 Constructor M1 limit M2 limit X limit Constructor B2 limit ----------------------------------- --------- Destructor X rjm2 1_m1 1_d2 1_b3 1_d1 005F7F88Destructor V2 005F7F98Destructor B2 1_b1 1_v1 1_b1 005F7F94 it can be seen that the object construction order is consistent with the sequence shown in the table. first construct the virtual base class sub-object 2. second, construct non-virtual base sub-objects. 3. construct the member itself 4. the construction order of the constructed object above the same level follows the declarative order from left to right. But the problem arises. 1: The Object Memory Distribution of this object X looks like this. It seems that the address is allocated backwards. Objects with similar first addresses are not the first objects to be allocated. Is a problem... How can we determine the distribution ??? My compilation platform is VS2010 Question 2: If class B1 contains a method, which memory function is called by the X object ?? I guess it's the one on the left. Write the test code. After the transformation, compilation turns out to find compilation problems 1> e: \ opensource \ exceptional c ++ style \ example_014class \ example_014class.cpp (191): error C2385: ambiguous access of 'fun '1> cocould be the 'fun' in base 'b1 '1> or cocould be the 'fun' in base 'b1 'it seems that the compiler cannot decide the X object which B1 function in the memory will be called. Is there no way? I think of the object model. I mentioned that virtual inheritance is used in this case. Check the transformed code. [Cpp] # include <map> struct classcomp {bool operator () (const _ int64 & lhs, const _ int64 & rhs) const {return lhs <rhs ;}}; std: multimap <__ int64, std: string, classcomp> m_Construtor; class B1 {public: B1 () {std :: cout <"Constructor B1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B1");} virtual ~ B1 () {std: cout <"Destructor B1" <this <'\ n';} void fun () {std :: cout <"fun B1" <this <'\ n' ;}}; class V1: virtual public B1 {public: V1 () {std :: cout <"Constructor V1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor V1");} virtual ~ V1 () {std: cout <"Destructor V1" <this <'\ n' ;}}; class D1: virtual public V1 {public: D1 () {std: cout <"Constructor D1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor D1");} virtual ~ D1 () {std: cout <"Destructor D1" <this <'\ n' ;}}; class B2 {public: B2 () {std :: cout <"Constructor B2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B2");} virtual ~ B2 () {std: cout <"Destructor B2" <this <'\ n' ;}}; class B3 {public: B3 () {std :: cout <"Constructor B3" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor B3");} virtual ~ B3 () {std: cout <"Destructor B3" <this <'\ n' ;}}; class V2: virtual public B1, public B2 {public: v2 () {std: cout <"Constructor V2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor V2");} virtual ~ V2 () {std: cout <"Destructor V2" <this <'\ n' ;}}; class D2: public B3, virtual public V2 {public: d2 () {std: cout <"Constructor D2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor D2");} virtual ~ D2 () {std: cout <"Destructor D2" <this <'\ n' ;}}; class M1 {public: M1 () {std :: cout <"Constructor M1" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor M1");} virtual ~ M1 () {std: cout <"Destructor M1" <this <'\ n' ;}}; class M2 {public: M2 () {std :: cout <"Constructor M2" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std: string> (_ int64) this, "Constructor M2");} virtual ~ M2 () {std: cout <"Destructor M2" <this <'\ n' ;}}; class X: public D1, public D2 {public: X () {std: cout <"Constructor X" <this <'\ n'; m_Construtor.insert (std: pair <__int64, std :: string> (_ int64) this, "Constructor X");} virtual ~ X () {std: cout <"Destructor X" <this <'\ n';} private: M1 _ m1; M2 _ m2 ;}; int _ tmain (int argc, _ TCHAR * argv []) {// B B; int I; X * pX = new X; std :: cout <"tests" <'\ n'; pX-> fun (); std: cout <"--------------------------------------------" <' \ n'; cout. setf (ios: showbase | ios: uppercase); // you can specify the uppercase characters in the base indicator output and the numbers to output std: multimap <__ int64, std: string, classcomp >:: iter Ator iter; for (iter = m_Construtor.begin (); iter! = M_Construtor.end (); ++ iter) // traverses {cout <std: hex <(* iter ). first <"" <(* iter ). second <endl;} std: cout <"------------------------------------------" <'\ n'; delete pX; pX = NULL; std: cin> I; return 0;} running result: Constructor B1 0020.f94constructor V1 000000f98constructor B2 1_v2 1_d1 000000f88constructor B3 000000f80constructor D2 000000f80constructor M1 000000f8cconst Ructor M2 ready X 00w.f80 fun B1 ready Constructor x0x0000f88 Constructor ready Constructor V2 ready ---------------------------- ---------------- Destructor X ready M2 ready M1 000000f8cdestructor D2 000000f80destructor B3 000000f80destructor D1 000000f88destructor V2 ready B2 ready V1 ready B1 000000f94 found that class B1 was rarely constructed. Haha ~~ It's really powerful ..

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.