Newing objects in constructor

Discussion in 'C++' started by tech, Jun 5, 2008.

  1. tech

    tech Guest

    Hi, Whenever i have a class that contains references to other classes
    i keep
    end up doing the below. However it doesn't seem so safe or elegant.
    How do the
    pros initialise subobjects, any ideas to improve the below would be
    welcome.

    /.h file
    class A
    {
    public:
    A();
    ~A();
    private:
    SomeMethod();

    obj1* pobj1;
    obj2* pobj2;
    obj3* pobj3;
    obj4* pobj4;
    };

    /.cpp file

    A::A()
    {
    pobj1 = new obj1;
    pobj2 = new obj2;
    pobj3 = new obj3;
    pobj4 = new obj4;

    }

    A::SomeMethod()
    {

    pobj1->doSomething();
    etc
    }

    A::~A()
    {
    delete pobj1;
    delete pobj2;
    delete pobj3;
    delete pobj4;
    }
    tech, Jun 5, 2008
    #1
    1. Advertising

  2. tech

    Kai-Uwe Bux Guest

    tech wrote:

    > Hi, Whenever i have a class that contains references to other classes
    > i keep
    > end up doing the below. However it doesn't seem so safe or elegant.
    > How do the
    > pros initialise subobjects, any ideas to improve the below would be
    > welcome.
    >
    > /.h file
    > class A
    > {
    > public:
    > A();
    > ~A();
    > private:
    > SomeMethod();
    >
    > obj1* pobj1;
    > obj2* pobj2;
    > obj3* pobj3;
    > obj4* pobj4;
    > };
    >
    > /.cpp file
    >
    > A::A()
    > {
    > pobj1 = new obj1;
    > pobj2 = new obj2;
    > pobj3 = new obj3;
    > pobj4 = new obj4;


    If the last new throws, you leak the memory for the first three objects. If
    you _really_ need pointers at all, consider using std::auto_ptr during
    initialization:

    A::A() {
    std::auto_ptr< obj1 > dummy1 ( new obj1 );
    std::auto_ptr< obj2 > dummy2 ( new obj2 );
    std::auto_ptr< obj3 > dummy3 ( new obj3 );
    std::auto_ptr< obj4 > dummy4 ( new obj4 );
    pobj1 = dummy1;
    pobj2 = dummy2;
    pobj3 = dummy3;
    pobj4 = dummy4;
    }

    >
    > }
    >
    > A::SomeMethod()
    > {
    >
    > pobj1->doSomething();
    > etc
    > }
    >
    > A::~A()
    > {
    > delete pobj1;
    > delete pobj2;
    > delete pobj3;
    > delete pobj4;
    > }


    If you go with those pointers, you either need to make the assignment
    operator and copy constructor private or implement them in some way that
    does the RightThing(tm), whatever that would be in your case. The ones
    generated by the compiler will _not_ do the right thing.


    More importantly: why do you want pointers in the first place? You could
    just do

    class A {
    type1 obj1;
    type2 obj2;
    ...
    };

    Nothing in your post shows a genuine need for pointer members.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 5, 2008
    #2
    1. Advertising

  3. Hi!

    Kai-Uwe Bux schrieb:
    > A::A() {
    > std::auto_ptr< obj1 > dummy1 ( new obj1 );
    > std::auto_ptr< obj2 > dummy2 ( new obj2 );
    > std::auto_ptr< obj3 > dummy3 ( new obj3 );
    > std::auto_ptr< obj4 > dummy4 ( new obj4 );
    > pobj1 = dummy1;


    You need to "release()" the object from the auto_ptr:
    pobj1 = dummy1.release();

    But it would be easier to just use auto_ptrs as members (if you _really_
    need pointers after all):

    class A {
    //use const until you implement operator =
    const std::auto_ptr<obj1> pobj1;
    A();
    };

    A::A()
    : pobj1(new obj1)
    {}

    Frank
    Frank Birbacher, Jun 5, 2008
    #3
  4. tech

    bjeremy Guest


    >
    > If the last new throws, you leak the memory for the first three objects. If
    > you _really_ need pointers at all, consider using std::auto_ptr during
    > initialization:
    >
    > A::A() {
    > std::auto_ptr< obj1 > dummy1 ( new obj1 );
    > std::auto_ptr< obj2 > dummy2 ( new obj2 );
    > std::auto_ptr< obj3 > dummy3 ( new obj3 );
    > std::auto_ptr< obj4 > dummy4 ( new obj4 );
    > pobj1 = dummy1;
    > pobj2 = dummy2;
    > pobj3 = dummy3;
    > pobj4 = dummy4;
    > }



    Actually, I could be seeing something correctly, but won't all your
    pointers be destroyed as soon as you leave the scope of the
    constructor? Don't you either have to explicitly release the auto_ptr
    (i.e. dummy1.release()) after the assignment... of if you can,
    declare your pointers in your class as auto_ptrs i.e.:

    /.h file
    class A
    {
    public:
    A();
    ~A();
    private:
    SomeMethod();

    std::auto_ptr< obj1 > myobj1;
    std::auto_ptr< obj2 > myobj2;
    std::auto_ptr< obj3 > myobj3;
    std::auto_ptr< obj4 > myobj4;

    };

    A::A()
    : myobj1(new obj1),
    myobj2(new obj2),
    myobj3(new obj3),
    myobj4(new obj4)
    {
    }

    Of course, they do not have to be auto_ptrs I guess... but using some
    type of smart pointer in the declaration may make your life easier
    than just using raw pointers.
    bjeremy, Jun 5, 2008
    #4
  5. tech

    Kai-Uwe Bux Guest

    bjeremy wrote:

    >
    >>
    >> If the last new throws, you leak the memory for the first three objects.
    >> If you _really_ need pointers at all, consider using std::auto_ptr during
    >> initialization:
    >>
    >> A::A() {
    >> std::auto_ptr< obj1 > dummy1 ( new obj1 );
    >> std::auto_ptr< obj2 > dummy2 ( new obj2 );
    >> std::auto_ptr< obj3 > dummy3 ( new obj3 );
    >> std::auto_ptr< obj4 > dummy4 ( new obj4 );
    >> pobj1 = dummy1;
    >> pobj2 = dummy2;
    >> pobj3 = dummy3;
    >> pobj4 = dummy4;
    >> }

    >
    >
    > Actually, I could be seeing something correctly, but won't all your
    > pointers be destroyed as soon as you leave the scope of the
    > constructor?


    Oops. That should be

    pobj1 = dummy1.release();
    ...

    > Don't you either have to explicitly release the auto_ptr
    > (i.e. dummy1.release()) after the assignment... of if you can,
    > declare your pointers in your class as auto_ptrs i.e.:
    >
    > /.h file
    > class A
    > {
    > public:
    > A();
    > ~A();
    > private:
    > SomeMethod();
    >
    > std::auto_ptr< obj1 > myobj1;
    > std::auto_ptr< obj2 > myobj2;
    > std::auto_ptr< obj3 > myobj3;
    > std::auto_ptr< obj4 > myobj4;
    >
    > };
    >
    > A::A()
    > : myobj1(new obj1),
    > myobj2(new obj2),
    > myobj3(new obj3),
    > myobj4(new obj4)
    > {
    > }
    >
    > Of course, they do not have to be auto_ptrs I guess... but using some
    > type of smart pointer in the declaration may make your life easier
    > than just using raw pointers.


    Yes.


    Thanks

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 5, 2008
    #5
  6. tech

    tech Guest

    Thanks for all the replies, one further question

    if i don't usse pointers but object members instead i need to include
    the header files rather than forward declare. Isn't this an argument
    against having member objects?
    tech, Jun 9, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Giulio
    Replies:
    9
    Views:
    1,026
    Patrick Kowalzick
    Jun 25, 2003
  2. asimorio
    Replies:
    11
    Views:
    708
    Tomás
    May 31, 2006
  3. asimorio
    Replies:
    4
    Views:
    298
    Default User
    May 31, 2006
  4. 7stud
    Replies:
    11
    Views:
    667
    Dennis Lee Bieber
    Mar 20, 2007
  5. Generic Usenet Account
    Replies:
    10
    Views:
    2,190
Loading...

Share This Page