Initialize an array of classes?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bob Altman

    Initialize an array of classes?

    Hi all,

    I have a class that contains a member variable that is an array of class
    instances:

    class MyClass {
    private:
    SomeClass m_someClass;
    SomeClass m_arrayOfClasse s[2];
    };

    Now, the SomeClass class doesn't have a default (paramterless) constructor,
    so I need to call its constructor in my initialization list of the MyClass
    constructor, kind of like this:

    // Constructor
    MyClass::MyClas s(void) :
    // This compiles ok
    m_someClass( constructor_arg uments ),

    // This doesn't compile
    m_arrayOfClasse s[0]( constructor_arg uments ),
    m_arrayOfClasse s[1]( constructor_arg uments )
    {}

    How do I initialize the array of class instances?

    TIA - Bob


  • Bob Altman

    #2
    Re: Initialize an array of classes?

    Here is a complete C++ console app example that demonstrates what I'm trying
    to do. The challenge is to change InnerValue to an array and figure out how
    to call the constructor for each element of the array.

    TIA - Bob

    #include "stdafx.h"
    #include <iostream>
    using namespace std;

    class CInner {
    public:
    // Constructor
    CInner(int x) : Value(x) {}

    // Member variable
    int Value;
    };

    class COuter {
    public:
    CInner InnerValue;

    // Constructor
    COuter() :
    InnerValue(2)
    {}
    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    COuter x;
    cout << x.InnerValue.Va lue << endl;
    return 0;
    }


    Comment

    • Bob Altman

      #3
      Re: Initialize an array of classes?

      Well, I found a way to get kind of what I'm after. Instead of trying to
      have an array of class instances, I can create an array of pointers to class
      instances. That way I can use the "new" operator in the body of the
      constructor to initialize the array. Of course, this means that I need to
      go through my code and change all of the relevant "." operators to "->"
      operators, but that's easily enough done in this case.

      But I'm still curious as to whether or not it's possible to initialize an
      array of classes if the class doesn't have a default constructor.


      Comment

      • David Wilkinson

        #4
        Re: Initialize an array of classes?

        Bob Altman wrote:
        Hi all,
        >
        I have a class that contains a member variable that is an array of class
        instances:
        >
        class MyClass {
        private:
        SomeClass m_someClass;
        SomeClass m_arrayOfClasse s[2];
        };
        >
        Now, the SomeClass class doesn't have a default (paramterless) constructor,
        so I need to call its constructor in my initialization list of the MyClass
        constructor, kind of like this:
        >
        // Constructor
        MyClass::MyClas s(void) :
        // This compiles ok
        m_someClass( constructor_arg uments ),
        >
        // This doesn't compile
        m_arrayOfClasse s[0]( constructor_arg uments ),
        m_arrayOfClasse s[1]( constructor_arg uments )
        {}
        >
        How do I initialize the array of class instances?
        Bob:

        If SomeClass is copyable you can do

        MyClass::MyClas s():
        m_someClass( constructor_arg uments )
        {
        m_arrayOfClasse s[0] = SomeClass( constructor_arg uments0 );
        m_arrayOfClasse s[1] = SomeClass( constructor_arg uments1 );
        }

        --
        David Wilkinson
        Visual C++ MVP

        Comment

        • Bo Persson

          #5
          Re: Initialize an array of classes?

          Bob Altman wrote:
          Well, I found a way to get kind of what I'm after. Instead of
          trying to have an array of class instances, I can create an array
          of pointers to class instances. That way I can use the "new"
          operator in the body of the constructor to initialize the array. Of
          course, this means that I need to go through my code and change
          all of the relevant "." operators to "->" operators, but that's
          easily enough done in this case.
          But I'm still curious as to whether or not it's possible to
          initialize an array of classes if the class doesn't have a default
          constructor.
          No, there is no way of initializing member array in the current
          language.

          In the upcoming revision, C++09, there is a generalized "initialize r
          list" feature that will possibly help in cases like this.


          Bo Persson


          Comment

          • Charles Wang [MSFT]

            #6
            Re: Initialize an array of classes?

            Hi Bob,
            Currently you cannot use member initialization list for a nonstatic array of a class if it does not have a default constructor. When you try to initialize the array, you will encounter the compiler
            error C2536. You may refer to:
            Compiler Error C2536


            If the class has a default constructor, you can explicitly initialize it like the following code:
            class CInner {
            public:
            // Constructor
            CInner(int x) : Value(x) {}
            CInner(){}

            // Member variable
            int Value;
            };

            class COuter {
            public:
            CInner InnerValue;
            CInner m_Inners[2];

            // Constructor
            COuter() :
            InnerValue(2),m _Inners()
            {}
            };

            The code can be compiled, however you may encounter the warning C4351 and I do not think that it is useful to use such initialization for an array.
            You can refer to this article for further inforamtion:
            Compiler Warning (level 1) C4351


            Best regards,
            Charles Wang
            Microsoft Online Community Support
            =============== =============== =============== ==============
            Delighting our customers is our #1 priority. We welcome your
            comments and suggestions about how we can improve the
            support we provide to you. Please feel free to let my manager
            know what you think of the level of service provided. You can
            send feedback directly to my manager at: msdnmg@microsof t.com.
            =============== =============== =============== ==============
            Get notification to my posts through email? Please refer to
            http://msdn.microsoft.com/subscripti...#notifications.

            Note: The MSDN Managed Newsgroup support offering is for
            non-urgent issues where an initial response from the community
            or a Microsoft Support Engineer within 1 business day is acceptable.
            Please note that each follow up response may take approximately
            2 business days as the support professional working with you may
            need further investigation to reach the most efficient resolution.
            The offering is not appropriate for situations
            that require urgent, real-time or phone-based interactions or complex
            project analysis and dump analysis issues. Issues of this nature are best
            handled working with a dedicated Microsoft Support Engineer by
            contacting Microsoft Customer Support Services (CSS) at
            http://msdn.microsoft.com/subscripti...t/default.aspx.
            =============== =============== =============== ===============
            This posting is provided "AS IS" with no warranties, and confers no rights.
            =============== =============== =============== ============


            Comment

            • Ben Voigt [C++ MVP]

              #7
              Re: Initialize an array of classes?

              David Wilkinson wrote:
              Bob Altman wrote:
              >Hi all,
              >>
              >I have a class that contains a member variable that is an array of
              >class instances:
              >>
              >class MyClass {
              >private:
              > SomeClass m_someClass;
              > SomeClass m_arrayOfClasse s[2];
              >};
              >>
              >Now, the SomeClass class doesn't have a default (paramterless)
              >constructor, so I need to call its constructor in my initialization
              >list of the MyClass constructor, kind of like this:
              >>
              >// Constructor
              >MyClass::MyCla ss(void) :
              > // This compiles ok
              > m_someClass( constructor_arg uments ),
              >>
              > // This doesn't compile
              > m_arrayOfClasse s[0]( constructor_arg uments ),
              > m_arrayOfClasse s[1]( constructor_arg uments )
              >{}
              >>
              >How do I initialize the array of class instances?
              >
              Bob:
              >
              If SomeClass is copyable you can do
              >
              MyClass::MyClas s():
              m_someClass( constructor_arg uments )
              {
              m_arrayOfClasse s[0] = SomeClass( constructor_arg uments0 );
              m_arrayOfClasse s[1] = SomeClass( constructor_arg uments1 );
              }
              Don't think so... all members have to be fully constructed before the body
              of the user-defined constructor begins to execute. With no parameter-less
              constructor, and no way to pass parameters to the array element
              constructors, it's not possible.

              OTOH, you should be able to make a fixed-length std::vector alike that does
              this, using an embedded char array, sizeof, and placement new. Be careful
              about destroying the right set of already-fully-constructed elements if any
              of the element constructors throw, be careful to destroy the elements in the
              array's destructor, and block copy construction and assignment operators,
              and you should be golden. This will, of course, be a lot more general in
              C++0x with variadic templates and closures, but C++03 is perfectly capable
              of making a type-specific initializable array class.


              Comment

              • David Wilkinson

                #8
                Re: Initialize an array of classes?

                Ben Voigt [C++ MVP] wrote:
                David Wilkinson wrote:
                >Bob Altman wrote:
                >>Hi all,
                >>>
                >>I have a class that contains a member variable that is an array of
                >>class instances:
                >>>
                >>class MyClass {
                >>private:
                >> SomeClass m_someClass;
                >> SomeClass m_arrayOfClasse s[2];
                >>};
                >>>
                >>Now, the SomeClass class doesn't have a default (paramterless)
                >>constructor , so I need to call its constructor in my initialization
                >>list of the MyClass constructor, kind of like this:
                >>>
                >>// Constructor
                >>MyClass::MyCl ass(void) :
                >> // This compiles ok
                >> m_someClass( constructor_arg uments ),
                >>>
                >> // This doesn't compile
                >> m_arrayOfClasse s[0]( constructor_arg uments ),
                >> m_arrayOfClasse s[1]( constructor_arg uments )
                >>{}
                >>>
                >>How do I initialize the array of class instances?
                >Bob:
                >>
                >If SomeClass is copyable you can do
                >>
                >MyClass::MyCla ss():
                >m_someClass( constructor_arg uments )
                >{
                > m_arrayOfClasse s[0] = SomeClass( constructor_arg uments0 );
                > m_arrayOfClasse s[1] = SomeClass( constructor_arg uments1 );
                >}
                >
                Don't think so... all members have to be fully constructed before the body
                of the user-defined constructor begins to execute. With no parameter-less
                constructor, and no way to pass parameters to the array element
                constructors, it's not possible.
                >
                OTOH, you should be able to make a fixed-length std::vector alike that does
                this, using an embedded char array, sizeof, and placement new. Be careful
                about destroying the right set of already-fully-constructed elements if any
                of the element constructors throw, be careful to destroy the elements in the
                array's destructor, and block copy construction and assignment operators,
                and you should be golden. This will, of course, be a lot more general in
                C++0x with variadic templates and closures, but C++03 is perfectly capable
                of making a type-specific initializable array class.
                Ben:

                Mmmm, I guess you're right. Oh well.

                Of course, this could be fixed by creating a default constructor for SomeClass...

                --
                David Wilkinson
                Visual C++ MVP

                Comment

                • =?Utf-8?B?UGF1bCBQYXZsaWNrbw==?=

                  #9
                  Re: Initialize an array of classes?

                  Bob - I am trying to do something very similar by having an array of a class
                  inside the other class but have the array created dynamically through the
                  main class constructor.

                  can I see your code on how you did this with the pointers?


                  "Bob Altman" wrote:
                  Well, I found a way to get kind of what I'm after. Instead of trying to
                  have an array of class instances, I can create an array of pointers to class
                  instances. That way I can use the "new" operator in the body of the
                  constructor to initialize the array. Of course, this means that I need to
                  go through my code and change all of the relevant "." operators to "->"
                  operators, but that's easily enough done in this case.
                  >
                  But I'm still curious as to whether or not it's possible to initialize an
                  array of classes if the class doesn't have a default constructor.
                  >
                  >
                  >

                  Comment

                  • Ben Voigt [C++ MVP]

                    #10
                    Re: Initialize an array of classes?

                    Paul Pavlicko wrote:
                    Bob - I am trying to do something very similar by having an array of
                    a class inside the other class but have the array created dynamically
                    through the main class constructor.
                    >
                    can I see your code on how you did this with the pointers?
                    Just use std::vector<Tfo r this, if a native class, or clr::array<Tif a
                    ref class.
                    >
                    >
                    "Bob Altman" wrote:
                    >
                    >Well, I found a way to get kind of what I'm after. Instead of
                    >trying to have an array of class instances, I can create an array of
                    >pointers to class instances. That way I can use the "new" operator
                    >in the body of the constructor to initialize the array. Of course,
                    >this means that I need to go through my code and change all of the
                    >relevant "." operators to "->" operators, but that's easily enough
                    >done in this case.
                    >>
                    >But I'm still curious as to whether or not it's possible to
                    >initialize an array of classes if the class doesn't have a default
                    >constructor.

                    Comment

                    • Bob Altman

                      #11
                      Re: Initialize an array of classes?

                      Thanks all. That answers my question.


                      Comment

                      • Bob Altman

                        #12
                        Re: Initialize an array of classes?

                        Paul, I just hacked up my original post. No guarantees that I didn't mangle
                        something...

                        #include "stdafx.h"
                        #include <iostream>
                        using namespace std;

                        class CInner {
                        public:
                        // Constructor
                        CInner(int x) : Value(x) {}

                        // Member variable
                        int Value;
                        };

                        class COuter {
                        public:
                        CInner InnerValue[5]; // Won't compile
                        CInner* InnerValue[5] // Array of pointers

                        // Constructor
                        COuter() :
                        // InnerValue(2) // Remove initializer
                        {
                        // Initialize the array in the body of the constructor
                        for (int i = 0; i < 5; i++) {
                        InnerValue[i] = new CInner(i);
                        }
                        }
                        };

                        int _tmain(int argc, _TCHAR* argv[])
                        {
                        COuter x;
                        cout << x.InnerValue.Va lue << endl;
                        return 0;
                        }


                        Comment

                        Working...