3

I need to initialize an array of objects of a parametrized constructor . How can i do it in best possible way ?

   # include<iostream>
   # include<conio.h>
   # include<stdio.h>

   using namespace std;

   class A
   {
    public:
    int a;       
    A();
    A(int x)
    {
     a=x;
    }      
   };
   int main()
   {
    A *a1,a2(1);
    a1 = (A*)malloc(sizeof(A)*10); // equivalent to A[10]. 
    for(int i=0;i<10;i++) a1[i]=a2; // Initialization is important in any program.
    for(int i=0;i<10;i++) cout<<a1[i].a; 
    getch(); 
    return 0;   
   }

This does work but is there some other way better than this ?

4
  • 1
    Why C's malloc and getch() instead of C++'s new and using iostream? Commented Feb 14, 2012 at 18:24
  • "This does work" No it doesn't; it invokes UB and only appears to work. Commented Feb 14, 2012 at 19:42
  • @ildjarn What do you mean by it invokes only UB ? I did not get what you mean to say by UB ? Commented Feb 14, 2012 at 19:45
  • @Ritesh : Undefined Behavior Commented Feb 14, 2012 at 19:45

3 Answers 3

4

The C++ way would be to use a std::vector.

std::vector<A>   a1(10, 1);

creates 10 A's initialized by 1.

Sign up to request clarification or add additional context in comments.

8 Comments

This requires A(int) to be not explicit I think ?
Probably, but it isn't in the example.
sure, wanted to be sure as I wanted to answer the very same thing but thought something was maybe amiss :)
The vector will destroy itself when it goes out of scope (at the end of main). Or you can call clear if you want to empty it earlier.
@Ritesh - You cannot just declare a destructor, you have to define it as well. But the above class doesn't need one.
|
0

This is solved using std::vector constructor taking size and base element :

A a2(1);
std::vector<A> tab(10, a2);

Comments

-1

Note that malloc does not construct objects, and so calling a1[i]=a2 is bad form. It probably seems to work fine since they are POD-ish objects, but this is not the proper way to do C++. It is undefined behavior, which is completely unpredictable. It may work ten thousand times in a row, and then erase your bank account. You should use new instead, which also constructs. Or better yet, use a vector, like the other answers suggest. Also, be sure that the default constructor initializes the data, and initialization will be less of a worry.

If you really must use malloc, the "correct way" to initialize is this:

std::uninitialized_copy(a1, a1+10, a2); //constructs and assigns

which is roughly equivalent to:

{
    int i=0;
    try {
        for(i=0; i<10; ++i)
           new(a1+i)A(a2); //constructs and initializes in the buffer
    } catch(...) { 
        try {
            for(; i>=0; --i)
               (a1+i)->~A(); //destroy if an error occured
        } catch(...) { 
            std::terminate();
        }
        throw;
    }
}

5 Comments

I wouldn't expect the A(int) constructor to throw. Or the default copy constructor.
@BoPersson: true, but when he does this again with std::string, and is surprised that his program crashes? I'll teach the generic correct (and easy!) way.
"and I'm pretty sure it's undefined behavior" It definitely is.
@ildjarn: I wasn't 100% sure, since the definition of POD has changed, and PODs are exceptions to some relevant rules.
@MooingDuck +1 For Genric Correct way :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.