Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to call a constructor in another constructor

How to call a constructor in another constructor

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialquestionlearning
12 Posts 9 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U User 33952

    Dear all, I have 2 constructors of the same class: CTest(){i = j = 0;}; CTest(int t){j = t;}; It is possible to call the first constructor in the second constructor? Of course, I can make an Initialize() method and I can call it in the both constructors. Thank you.

    C Offline
    C Offline
    CP Visitor
    wrote on last edited by
    #3

    http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3[^]

    T 1 Reply Last reply
    0
    • C CP Visitor

      http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3[^]

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #4

      Sorry, but that link is not correct. at least not completely. The way to call one constructor from another is to use "placement new". For example: Foo::Foo() { int i; new (this)Foo(i); // this will call the Foo::Foo(int) ctor without allocating memory } Foo::Foo(int) { } This begs the question of why you want to do this. If it is for "common" initialization code, the better answer is to have a separate initialization function, as in the following. Then call that init code either from each ctor, or perhaps better, to call it from the places where Foo is constructed. then maybe handle init failures there. bool Foo:init(some parameters here maybe) { // do init code here }

      B A 2 Replies Last reply
      0
      • T TheGreatAndPowerfulOz

        Sorry, but that link is not correct. at least not completely. The way to call one constructor from another is to use "placement new". For example: Foo::Foo() { int i; new (this)Foo(i); // this will call the Foo::Foo(int) ctor without allocating memory } Foo::Foo(int) { } This begs the question of why you want to do this. If it is for "common" initialization code, the better answer is to have a separate initialization function, as in the following. Then call that init code either from each ctor, or perhaps better, to call it from the places where Foo is constructed. then maybe handle init failures there. bool Foo:init(some parameters here maybe) { // do init code here }

        B Offline
        B Offline
        basementman
        wrote on last edited by
        #5

        Actually, you can call a constructor from the object itself. A constructor is just another function/method, but is called by the memory allocation scheme (IE: Operator new). You can also call the destructor any time you want, as a standard object method (EX: pMyObj->~MyObject(); ). Why would you want to do this? Consider the following: You want to allocate memory dynamically in a busy, multithreaded environment. Therefore, you want to avoid the heap. So, you decide dynamically allocate memory from the stack using _alloca(). In order to initialize this "object", you need to call the constructor. Also, when you are finished with this object, you MUST NOT "delete" it, but you should destroy it properly by calling the destructor. A non-tested example for thought purposes:

        #define STACK_OBJECT_NEW(c, p) {p = (c *)_alloca(sizeof(c)); if (p) p->c(); }
        #define STACK_OBJECT_DELETE(c, p) {if (p) p->~c(); }

        void MyFunc()
        {
        MyClass *p = NULL;

        STACK_OBJECT_NEW(MyClass, p);
        if (p)
        {
        p->InvokeSomeMethod();
        ...

          STACK\_OBJECT\_DELETE(MyClass, p);
        }
        

        }

        onwards and upwards...

        A 1 Reply Last reply
        0
        • U User 33952

          Dear all, I have 2 constructors of the same class: CTest(){i = j = 0;}; CTest(int t){j = t;}; It is possible to call the first constructor in the second constructor? Of course, I can make an Initialize() method and I can call it in the both constructors. Thank you.

          R Offline
          R Offline
          Ravi Bhavnani
          wrote on last edited by
          #6

          I would recommend going the way of the Initialize() method. It will make your code much easier to debug two years from now on a late, dark, rainy night with a customer expecting a bug fix early the next morning. /ravi My new year's resolution: 2048 x 1536 Home | Articles | Freeware | Music ravib@ravib.com

          1 Reply Last reply
          0
          • T TheGreatAndPowerfulOz

            Sorry, but that link is not correct. at least not completely. The way to call one constructor from another is to use "placement new". For example: Foo::Foo() { int i; new (this)Foo(i); // this will call the Foo::Foo(int) ctor without allocating memory } Foo::Foo(int) { } This begs the question of why you want to do this. If it is for "common" initialization code, the better answer is to have a separate initialization function, as in the following. Then call that init code either from each ctor, or perhaps better, to call it from the places where Foo is constructed. then maybe handle init failures there. bool Foo:init(some parameters here maybe) { // do init code here }

            A Offline
            A Offline
            Andrew Walker
            wrote on last edited by
            #7

            ahz wrote: The way to call one constructor from another is to use "placement new". This is incorrect. Herb Sutter - the current chairman of the C++ standards committee described this 'anti-idiom' as 'an abomination' and 'abhorrent' in the article 'delegating constructors' C/C++ Users Journal May 2003. For any data members that are not POD, this approach will fail, because the destructor of that data members will run only once, while the constructors will have run twice To the initial poster. The only way to solve this problem is with an initialization function, but you must also ensure that that function is not virtual.


            T 1 Reply Last reply
            0
            • B basementman

              Actually, you can call a constructor from the object itself. A constructor is just another function/method, but is called by the memory allocation scheme (IE: Operator new). You can also call the destructor any time you want, as a standard object method (EX: pMyObj->~MyObject(); ). Why would you want to do this? Consider the following: You want to allocate memory dynamically in a busy, multithreaded environment. Therefore, you want to avoid the heap. So, you decide dynamically allocate memory from the stack using _alloca(). In order to initialize this "object", you need to call the constructor. Also, when you are finished with this object, you MUST NOT "delete" it, but you should destroy it properly by calling the destructor. A non-tested example for thought purposes:

              #define STACK_OBJECT_NEW(c, p) {p = (c *)_alloca(sizeof(c)); if (p) p->c(); }
              #define STACK_OBJECT_DELETE(c, p) {if (p) p->~c(); }

              void MyFunc()
              {
              MyClass *p = NULL;

              STACK_OBJECT_NEW(MyClass, p);
              if (p)
              {
              p->InvokeSomeMethod();
              ...

                STACK\_OBJECT\_DELETE(MyClass, p);
              }
              

              }

              onwards and upwards...

              A Offline
              A Offline
              Anonymous
              wrote on last edited by
              #8

              We all know now that you are a guru. But keep the hack to yourself next time!

              B 1 Reply Last reply
              0
              • A Anonymous

                We all know now that you are a guru. But keep the hack to yourself next time!

                B Offline
                B Offline
                basementman
                wrote on last edited by
                #9

                you don't like my "hack"? :omg:  onwards and upwards...

                1 Reply Last reply
                0
                • A Andrew Walker

                  ahz wrote: The way to call one constructor from another is to use "placement new". This is incorrect. Herb Sutter - the current chairman of the C++ standards committee described this 'anti-idiom' as 'an abomination' and 'abhorrent' in the article 'delegating constructors' C/C++ Users Journal May 2003. For any data members that are not POD, this approach will fail, because the destructor of that data members will run only once, while the constructors will have run twice To the initial poster. The only way to solve this problem is with an initialization function, but you must also ensure that that function is not virtual.


                  T Offline
                  T Offline
                  TheGreatAndPowerfulOz
                  wrote on last edited by
                  #10

                  It may be frowned upon, and may even be abhorent, but is it not incorrect. The original poster asked a simple direct technical question and I gave a simple direct techinically correct answer. It is correct C++ syntax, it is technically correct, and it works --- albeit for simple cases. I wouldn't use it, and don't recommend it --- for Herb Sutters reasons --- and for many of my own reasons that I won't belabor here. However, I agree the best way to solve the issue is with an initialization function. However, I don't think it necessarily needs to be non-virtual. Depends on where you are calling the function from. If from the ctor, then yes make sure it's non-virtual. If from outside the ctor (the method I recommend, then it's ok to be virtual).

                  L 1 Reply Last reply
                  0
                  • T TheGreatAndPowerfulOz

                    It may be frowned upon, and may even be abhorent, but is it not incorrect. The original poster asked a simple direct technical question and I gave a simple direct techinically correct answer. It is correct C++ syntax, it is technically correct, and it works --- albeit for simple cases. I wouldn't use it, and don't recommend it --- for Herb Sutters reasons --- and for many of my own reasons that I won't belabor here. However, I agree the best way to solve the issue is with an initialization function. However, I don't think it necessarily needs to be non-virtual. Depends on where you are calling the function from. If from the ctor, then yes make sure it's non-virtual. If from outside the ctor (the method I recommend, then it's ok to be virtual).

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #11

                    ahz wrote: It may be frowned upon, and may even be abhorent, but is it not incorrect. The original poster asked a simple direct technical question and I gave a simple direct techinically correct answer. Wrong, wrong, wrong :( :mad: X| From: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3[^] "BTW do NOT try to achieve this via placement new. Some people think they can say new(this) Foo(x, int(x)+7) within the body of Foo::Foo(char). However that is bad, bad, bad. Please don't write me and tell me that it seems to work on your particular version of your particular compiler; it's bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no."

                    T 1 Reply Last reply
                    0
                    • L Lost User

                      ahz wrote: It may be frowned upon, and may even be abhorent, but is it not incorrect. The original poster asked a simple direct technical question and I gave a simple direct techinically correct answer. Wrong, wrong, wrong :( :mad: X| From: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3[^] "BTW do NOT try to achieve this via placement new. Some people think they can say new(this) Foo(x, int(x)+7) within the body of Foo::Foo(char). However that is bad, bad, bad. Please don't write me and tell me that it seems to work on your particular version of your particular compiler; it's bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no."

                      T Offline
                      T Offline
                      TheGreatAndPowerfulOz
                      wrote on last edited by
                      #12

                      I guess you can't read. It is correct. Whether you should do it is another thing altogether. LEARN TO READ!

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups