Thread: Initializing array and non-standard constructor

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    16

    Initializing array and non-standard constructor

    Hello! I was wondering, since you can initialize an array of let's say integers with the following statement:

    Code:
    int a[3] = {1, 2, 3};
    how would you go about initializing an array of objects of a given class CTest, using a self-defined constructor, e.g. CTest(int, int)?

    First thing that crossed my mind was this (and feel free to laugh as much as you like at my ignorance ):

    Code:
    CTest a[3] = {(1, 2), (3, 4), (5, 6)};
    but, as most of you may have guessed, it didn't work.

    So, is there a way to achieve this?

    Thanks!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If I'm not wrong, what you actually are trying to use would be the copy constructor.

    I'm not sure how it would work out, though.

  3. #3
    Registered User
    Join Date
    Oct 2003
    Posts
    16
    Thanks! After defining a copy constructor, I was able to get the desired result with the following statement:

    Code:
    CTest a[3] = {CTest(1, 2), CTest(3,4), CTest(5,6)};
    Thanks again!

  4. #4
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Just a guess here, but wouldn't that code create 6 CTests overall? There are three array elements AND three temporary instances that are used by the copy constructor to fill the array elements. Not really important, but there must be a way to avoid this. Something like your original idea, where you can specify parameters for a custom-constructor in the array initializer. Anybody?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Nope, only the three copies get created. Remember an array is very similar to a pointer. It will now point to an area in memory with the three class's are.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  6. #6
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    But, because it uses a copy constructor, doesn't that imply that it copies from one object to another? Therefore, CTest(1,2) in the initializer list must create a temporary instance, then be disposed of after initialization is done. Or is that wrong?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  7. #7
    Registered User
    Join Date
    Aug 2003
    Posts
    51
    wouldn't use copy constructor, it would use the constructor. Each element would just be constructed a single variable.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Originally posted by Kyro
    wouldn't use copy constructor, it would use the constructor. Each element would just be constructed a single variable.
    In that case, why did Jasel have to write a copy constructor for it to work?

  9. #9
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    It would seem logical for it to use the constructor. Then I agree that it wouldn't create extra objects, merely call the constructor with the specified parameters.

    That brings me to another point. In the following code:
    Code:
    CTest a[3] = {CTest(1, 2), CTest(3,4), CTest(5,6)};
    I'm supposing the default constructors for a[0],a[1] and a[2] are not called, because there is an initialization list with the construction specs. Is that correct?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  10. #10
    Registered User
    Join Date
    Aug 2003
    Posts
    51
    Originally posted by laserlight
    In that case, why did Jasel have to write a copy constructor for it to work?
    oh sorry didn't read that one. Must be a VC++ thing, i cause i didnt' have to write a copy constructor, just a constructor :S

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Originally posted by Kyro
    oh sorry didn't read that one. Must be a VC++ thing, i cause i didnt' have to write a copy constructor, just a constructor :S
    I tested in MinGW and no copy constructor was needed, so yeah, it could have been a compiler thing.

    Either that, or Jasel took my advice and changed the code to use the constructor, simultaneously.

  12. #12
    Registered User
    Join Date
    Aug 2003
    Posts
    51
    OK takin from stroustrup himself

    "Except by using an initializer list, there is no way to specify explicit arguments for a constructor in an array declaration."

    he also goes on to write code for initialising differing values in the array by console input.

    So i guess really if u want to conform to the standard, u can't really do much about it other than std input.....

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Just to eliminate any confusion, run the following code:
    Code:
    #include <iostream>
    using namespace std;
    
    class A
    {
        int m_n;
    public:
        A(int n) : m_n(n) 
        {
            cout << "constructor A" << endl;
        }//constructor
    
        A(const A &a)
        {
            cout << "copyconstruct A" << endl;
            m_n = a.m_n;
        }//copy constructor
    };//A
    
    int main()
    {
        A a1(4);
    
        A array[] = {A(3), a1};
    
        return 0;
    }//main
    /*
    Output:
     constructor A
     constructor A
     copyconstruct A
    */
    The first call to the constructor is for a1.
    The second call to the constructor is for array[0].
    The copy constructor call is for array[1] and a1 is the parameter.

    You don't have to allocate off the heap if the array size if fixed. Consider the following code.
    Code:
    int main()
    {
        int n[] = {0, 1, 2, 3, 4};
    
        A array[] = {A(n[0]), A(n[1]), A(n[2]), A(n[3]), A(n[4])};
    
        return 0;
    }//main
    Whe in doubt, write some test code.

    gg

  14. #14
    Registered User
    Join Date
    Oct 2003
    Posts
    16
    Ok, after reading your posts, I've realized that what was missing from my original attempt was not the copy constructor, but the word CTest before each pair of values in the initialization... lol, I just tried two changes at the same time (definition of a copy constructor and use of the word CTest) and wrongly assumed that the program then worked thanks to the copy constructor, when in fact was the word that was saving the day! Sorry for any confusion, and thanks for your comments.

  15. #15
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    I was wrong, ignore this post.
    Last edited by Cat; 11-10-2003 at 03:47 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed