Initializing composed objects

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • alacrite@gmail.com

    #1

    Initializing composed objects

    If I have this situation

    class X
    {
    Z z;
    Y y;
    };

    Class X has two objects of type Z and Y. How do I initialize z and y
    with non default constructors?

    X::X()
    {
    z(1);
    y(2);
    }

    If I do something like the previous I get the following error:

    line 2, Error: Could not find Z::Z() to initialize z.
    line 2, Error: Could not find Y::Y() to initialize y.
    line 3, Error: Only a function may be called.
    line 3, Error: Only a function may be called.

  • Victor Bazarov

    #2
    Re: Initializing composed objects

    alacrite@gmail. com wrote:
    If I have this situation
    >
    class X
    {
    Z z;
    Y y;
    };
    >
    Class X has two objects of type Z and Y. How do I initialize z and y
    with non default constructors?
    Use the constructor _initializer_li st_ (look it up).
    >
    X::X()
    {
    z(1);
    y(2);
    }
    >
    If I do something like the previous I get the following error:
    >
    line 2, Error: Could not find Z::Z() to initialize z.
    line 2, Error: Could not find Y::Y() to initialize y.
    line 3, Error: Only a function may be called.
    line 3, Error: Only a function may be called.
    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Salt_Peter

      #3
      Re: Initializing composed objects


      alacrite@gmail. com wrote:
      If I have this situation
      >
      class X
      {
      Z z;
      Y y;
      };
      >
      Class X has two objects of type Z and Y. How do I initialize z and y
      with non default constructors?
      >
      X::X()
      {
      z(1);
      y(2);
      }
      The exact same way you would initialize Z if it had a member.

      class Z
      {
      int z;
      public:
      Z() : z(0) { } // def ctor
      Z(int n) : z(n) { } // parametized ctor
      };

      int main()
      {
      Z instance_0; // instance_0.z == 0
      Z instance_1(1); // instance_1.z == 1
      }

      Comment

      • alacrite@gmail.com

        #4
        Re: Initializing composed objects


        Salt_Peter wrote:
        alacrite@gmail. com wrote:
        If I have this situation

        class X
        {
        Z z;
        Y y;
        };

        Class X has two objects of type Z and Y. How do I initialize z and y
        with non default constructors?

        X::X()
        {
        z(1);
        y(2);
        }
        >
        The exact same way you would initialize Z if it had a member.
        >
        class Z
        {
        int z;
        public:
        Z() : z(0) { } // def ctor
        Z(int n) : z(n) { } // parametized ctor
        };
        >
        int main()
        {
        Z instance_0; // instance_0.z == 0
        Z instance_1(1); // instance_1.z == 1
        }
        The goal of what I am trying to do is to give some variables of type Z
        and Y scope of class X but delay there initalization until all other
        dependencies have been met. For example the Constructor of X may have
        to go to the database before it can populate Z and Y with thier values.
        So in that case I don't think constructor initalizer list technique
        would be able to be used in that case.

        Comment

        • Victor Bazarov

          #5
          Re: Initializing composed objects

          alacrite@gmail. com wrote:
          Salt_Peter wrote:
          >alacrite@gmail. com wrote:
          >>If I have this situation
          >>>
          >>class X
          >>{
          >> Z z;
          >> Y y;
          >>};
          >>>
          >>Class X has two objects of type Z and Y. How do I initialize z and y
          >>with non default constructors?
          >>>
          >>X::X()
          >>{
          >> z(1);
          >> y(2);
          >>}
          >[...]
          >
          The goal of what I am trying to do is to give some variables of type Z
          and Y scope of class X but delay there initalization until all other
          dependencies have been met. For example the Constructor of X may have
          to go to the database before it can populate Z and Y with thier
          values. So in that case I don't think constructor initalizer list
          technique would be able to be used in that case.
          You cannot *initialise* them that way. You can only hope to *assign*
          them at best, if you have to do

          X::X()
          {
          /* some complicated processing */
          z = Z(somevalue_fro m_processing);
          y = Y(someothervalu e);
          }

          Now, since your 'Z' and 'Y' don't seem to have default constructors,
          you _have_ to provide some values to *initialise* the members with.
          So, it gets ugly relatively quickly:

          X::X() : z(dummy_value_f or_z), y(dummy_value_f or_y)
          {
          /* some complicated processing */
          z = Z(somevalue_fro m_processing);
          y = Y(someothervalu e);
          }

          Perhaps you can re-design your initialisation procedure...

          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask


          Comment

          • Salt_Peter

            #6
            Re: Initializing composed objects


            alacr...@gmail. com wrote:
            Salt_Peter wrote:
            alacrite@gmail. com wrote:
            If I have this situation
            >
            class X
            {
            Z z;
            Y y;
            };
            >
            Class X has two objects of type Z and Y. How do I initialize z and y
            with non default constructors?
            >
            X::X()
            {
            z(1);
            y(2);
            }
            The exact same way you would initialize Z if it had a member.

            class Z
            {
            int z;
            public:
            Z() : z(0) { } // def ctor
            Z(int n) : z(n) { } // parametized ctor
            };

            int main()
            {
            Z instance_0; // instance_0.z == 0
            Z instance_1(1); // instance_1.z == 1
            }
            >
            The goal of what I am trying to do is to give some variables of type Z
            and Y scope of class X but delay there initalization until all other
            dependencies have been met. For example the Constructor of X may have
            to go to the database before it can populate Z and Y with thier values.
            So in that case I don't think constructor initalizer list technique
            would be able to be used in that case.
            And why not? Whats preventing from initializing a variable to a valid
            state and then reset the variable with a some dependancy when
            available? Likewise, whats preventing you from completing some
            dependancy and still intialize the variables in that init list?

            Remember job #1, always , always initialize all your members. Even if
            you will never use them. Take as an example a pointer. If you set that
            pointer to 0 in the init list and happen to use it without
            initialization it by accident - the result and the solution will be
            obvious. If that pointer isn't initialized at all, you'll dig high and
            low for the bug for a week. The same applies for any member.

            Why take away the support a compiler can give you?
            Interestingly enough, take a look at what happens if you do have a
            dependancy:

            #include <iostream>

            class Z
            {
            char m_char;
            public:
            Z() : m_char( getInput() ) { std::cout << "Z()\n"; } // def ctor
            ~Z() { std::cout << "~Z()\n"; }
            /* member functions */
            char getInput() const
            {
            std::cout << "enter a char between b and e (default: a): ";
            char c;
            std::cin >c;
            if( (c >= 'b' && c <= 'e' ) && std::cin.good() )
            {
            return c;
            } else {
            return 'a';
            }
            }
            const char& get() const { return m_char; }
            };

            int main()
            {
            Z instance;
            std::cout << "instance.m_cha r = ";
            std::cout << instance.get() << std::endl;
            return 0;
            }

            /* sample output
            enter a character between b and e (default: a): c
            Z()
            instance.m_char = c
            ~Z()
            */

            Try a primitive array of Zs.

            Comment

            • alacrite@gmail.com

              #7
              Re: Initializing composed objects


              Salt_Peter wrote:
              alacr...@gmail. com wrote:
              Salt_Peter wrote:
              alacrite@gmail. com wrote:
              If I have this situation

              class X
              {
              Z z;
              Y y;
              };

              Class X has two objects of type Z and Y. How do I initialize z and y
              with non default constructors?

              X::X()
              {
              z(1);
              y(2);
              }
              >
              The exact same way you would initialize Z if it had a member.
              >
              class Z
              {
              int z;
              public:
              Z() : z(0) { } // def ctor
              Z(int n) : z(n) { } // parametized ctor
              };
              >
              int main()
              {
              Z instance_0; // instance_0.z == 0
              Z instance_1(1); // instance_1.z == 1
              }
              The goal of what I am trying to do is to give some variables of type Z
              and Y scope of class X but delay there initalization until all other
              dependencies have been met. For example the Constructor of X may have
              to go to the database before it can populate Z and Y with thier values.
              So in that case I don't think constructor initalizer list technique
              would be able to be used in that case.
              >
              And why not? Whats preventing from initializing a variable to a valid
              state and then reset the variable with a some dependancy when
              available? Likewise, whats preventing you from completing some
              dependancy and still intialize the variables in that init list?
              >
              Remember job #1, always , always initialize all your members. Even if
              you will never use them. Take as an example a pointer. If you set that
              pointer to 0 in the init list and happen to use it without
              initialization it by accident - the result and the solution will be
              obvious. If that pointer isn't initialized at all, you'll dig high and
              low for the bug for a week. The same applies for any member.
              >
              Why take away the support a compiler can give you?
              Interestingly enough, take a look at what happens if you do have a
              dependancy:
              >
              #include <iostream>
              >
              class Z
              {
              char m_char;
              public:
              Z() : m_char( getInput() ) { std::cout << "Z()\n"; } // def ctor
              ~Z() { std::cout << "~Z()\n"; }
              /* member functions */
              char getInput() const
              {
              std::cout << "enter a char between b and e (default: a): ";
              char c;
              std::cin >c;
              if( (c >= 'b' && c <= 'e' ) && std::cin.good() )
              {
              return c;
              } else {
              return 'a';
              }
              }
              const char& get() const { return m_char; }
              };
              >
              int main()
              {
              Z instance;
              std::cout << "instance.m_cha r = ";
              std::cout << instance.get() << std::endl;
              return 0;
              }
              >
              /* sample output
              enter a character between b and e (default: a): c
              Z()
              instance.m_char = c
              ~Z()
              */
              >
              Try a primitive array of Zs.
              Ok, After the last two responses I understand the situation much
              better. So thank you Victor Bazarov and Salt_Peter for the help.

              Comment

              Working...