questions about pointers in container

Discussion in 'C++' started by tradevol@yahoo.com, Aug 4, 2008.

  1. Guest

    as this example,

    question:

    If my purpose is initialize data from xml files and store them in the
    vector, so they can be used in class B by other member functions, do
    you think functionP is a viable function(will a could go away after
    out of the function)?
    If not, is there a better solution than using functionPt?

    I read that it is not a good design to have container for pointers(C++
    FAQs), but I cannot see how I can get around it in my situation.

    Newbie questions, thanks for the help

    Chris

    class A{
    ....
    }

    class B{

    void functionPt(){
    ...
    A* aPt ;
    vPt.push_back(aPt);

    }

    void functionP(){
    ...
    A a;
    v.push_back(a);
    }



    private:
    vector<A*> vPt;
    vector<A> v;

    }
     
    , Aug 4, 2008
    #1
    1. Advertising

  2. Guest

    On Aug 3, 4:38 pm, wrote:

    > If my purpose is initialize data from xml files and store them in the
    > vector, so they can be used in class B by other member functions, do
    > you think functionP is a viable function(will a could go away after
    > out of the function)?


    > void functionP(){
    > ...
    > A a;
    > v.push_back(a);
    >
    > }


    That would work. Yes, 'a' would be terminated at the end of functionP.
    Since 'v' would be containing a *copy* of 'a' you are good.

    > If not, is there a better solution than using functionPt?


    > void functionPt(){
    > ...
    > A* aPt ;
    > vPt.push_back(aPt);
    >
    > }


    You would need a vector of pointers if the objects that you create a
    polymorphic. Otherwise go with functionP.

    > I read that it is not a good design to have container for pointers(C++
    > FAQs), but I cannot see how I can get around it in my situation.


    If you have polymorphic objects, store them either as smart pointers
    in a vector, or use a "pointer vector" that knowns to delete the
    objects when itself is going away.

    Using the Boost library's reference counted pointer:

    #include <boost/shared_ptr.hpp>

    typedef boost::shared_ptr<A> APtr;
    typedef vector<APtr> APointers;

    APointers my_a_collection;
    my_a_collection.push_back(APtr(new SomeDecendentOfA()));

    See the Boost library for their pointer vector.

    Ali
     
    , Aug 4, 2008
    #2
    1. Advertising

  3. Guest

    On Aug 3, 7:50 pm, "Daniel T." <> wrote:
    > wrote:
    > > as this example,

    >
    > > question:

    >
    > > If my purpose is initialize data from xml files and store them in the
    > > vector, so they can be used in class B by other member functions, do
    > > you think functionP is a viable function(will a could go away after
    > > out of the function)?
    > > If not, is there a better solution than using functionPt?

    >
    > > I read that it is not a good design to have container for pointers(C++
    > > FAQs), but I cannot see how I can get around it in my situation.

    >
    > > Newbie questions, thanks for the help

    >
    > > Chris

    >
    > > class A{
    > > ....
    > > }

    >
    > > class B{

    >
    > > void functionPt(){
    > > ...
    > > A* aPt ;

    >
    > aPt has not been initialized. Copying it into a vector is technically
    > undefined behavior.
    >
    > > vPt.push_back(aPt);

    >
    > > }

    >
    > > void functionP(){
    > > ...
    > > A a;
    > > v.push_back(a);
    > > }

    >
    > > private:
    > > vector<A*> vPt;
    > > vector<A> v;

    >
    > > }


    Thanks. My fault. My intention is A* aPt = new A;
     
    , Aug 4, 2008
    #3
  4. Guest

    On Aug 3, 7:07 pm, wrote:
    > On Aug 3, 4:38 pm, wrote:
    >
    > > If my purpose is initialize data from xml files and store them in the
    > > vector, so they can be used in class B by other member functions, do
    > > you think functionP is a viable function(will a could go away after
    > > out of the function)?
    > > void functionP(){
    > > ...
    > > A a;
    > > v.push_back(a);

    >
    > > }

    >
    > That would work. Yes, 'a' would be terminated at the end of functionP.
    > Since 'v' would be containing a *copy* of 'a' you are good.
    >
    > > If not, is there a better solution than using functionPt?
    > > void functionPt(){
    > > ...
    > > A* aPt ;
    > > vPt.push_back(aPt);

    >
    > > }

    >
    > You would need a vector of pointers if the objects that you create a
    > polymorphic. Otherwise go with functionP.
    >
    > > I read that it is not a good design to have container for pointers(C++
    > > FAQs), but I cannot see how I can get around it in my situation.

    >
    > If you have polymorphic objects, store them either as smart pointers
    > in a vector, or use a "pointer vector" that knowns to delete the
    > objects when itself is going away.
    >
    > Using the Boost library's reference counted pointer:
    >
    > #include <boost/shared_ptr.hpp>
    >
    > typedef boost::shared_ptr<A> APtr;
    > typedef vector<APtr> APointers;
    >
    > APointers my_a_collection;
    > my_a_collection.push_back(APtr(new SomeDecendentOfA()));
    >
    > See the Boost library for their pointer vector.
    >
    > Ali



    Thanks Ali. Basically, when push_back is called, A's copy constructor
    is triggered and there is a copy of a is made and stored in v. And
    since v's scope is the class, the copy will not be destroyed as long
    as the class instance is alive. please correct me if i am wrong.

    Heard about boost, but never used it before. Will auto_ptr do the same
    thing in this case (in case A could be polymorphic )?
    thanks

    Chris
     
    , Aug 4, 2008
    #4
  5. Guest

    On Aug 3, 6:30 pm, wrote:

    > Will auto_ptr do the same
    > thing in this case (in case A could be polymorphic )?


    Unfortunately, std::auto_ptr can not be used with standard containers
    because it doesn't satisfy the requirement that the copies are
    equivalent. Source auto_ptr becomes "null" when auto_ptr objects are
    copied.

    Ali
     
    , Aug 4, 2008
    #5
  6. Daniel T. Guest

    On Aug 3, 9:20 pm, wrote:
    > On Aug 3, 7:50 pm, "Daniel T." <> wrote:
    >
    >
    >
    >
    >
    > > wrote:
    > > > as this example,

    >
    > > > question:

    >
    > > > If my purpose is initialize data from xml files and store them in the
    > > > vector, so they can be used in class B by other member functions, do
    > > > you think functionP is a viable function(will a could go away after
    > > > out of the function)?
    > > > If not, is there a better solution than using functionPt?

    >
    > > > I read that it is not a good design to have container for pointers(C++
    > > > FAQs), but I cannot see how I can get around it in my situation.

    >
    > > > Newbie questions, thanks for the help

    >
    > > > Chris

    >
    > > > class A{
    > > >    ....
    > > > }

    >
    > > > class B{

    >
    > > > void functionPt(){
    > > >  ...
    > > >   A* aPt ;

    >
    > > aPt has not been initialized. Copying it into a vector is technically
    > > undefined behavior.

    >
    > > >   vPt.push_back(aPt);

    >
    > > > }

    >
    > > > void functionP(){
    > > >   ...
    > > >   A a;
    > > >    v.push_back(a);
    > > > }

    >
    > > > private:
    > > >    vector<A*> vPt;
    > > >    vector<A>  v;

    >
    > > > }

    >
    > Thanks. My fault. My intention is A* aPt = new A;


    Now you have a leak.
     
    Daniel T., Aug 4, 2008
    #6
  7. Guest

    On Aug 4, 1:48 pm, "Daniel T." <> wrote:
    > On Aug 3, 9:20 pm, wrote:
    >
    >
    >
    > > On Aug 3, 7:50 pm, "Daniel T." <> wrote:

    >
    > > > wrote:
    > > > > as this example,

    >
    > > > > question:

    >
    > > > > If my purpose is initialize data from xml files and store them in the
    > > > > vector, so they can be used in class B by other member functions, do
    > > > > you think functionP is a viable function(will a could go away after
    > > > > out of the function)?
    > > > > If not, is there a better solution than using functionPt?

    >
    > > > > I read that it is not a good design to have container for pointers(C++
    > > > > FAQs), but I cannot see how I can get around it in my situation.

    >
    > > > > Newbie questions, thanks for the help

    >
    > > > > Chris

    >
    > > > > class A{
    > > > >    ....
    > > > > }

    >
    > > > > class B{

    >
    > > > > void functionPt(){
    > > > >  ...
    > > > >   A* aPt ;

    >
    > > > aPt has not been initialized. Copying it into a vector is technically
    > > > undefined behavior.

    >
    > > > >   vPt.push_back(aPt);

    >
    > > > > }

    >
    > > > > void functionP(){
    > > > >   ...
    > > > >   A a;
    > > > >    v.push_back(a);
    > > > > }

    >
    > > > > private:
    > > > >    vector<A*> vPt;
    > > > >    vector<A>  v;

    >
    > > > > }

    >
    > > Thanks. My fault. My intention is A* aPt = new A;

    >
    > Now you have a leak.


    not really. my ~B will iterate the vector and call delete.
     
    , Aug 6, 2008
    #7
  8. Guest

    On Aug 6, 7:09 pm, "Daniel T." <> wrote:
    > wrote:
    > > "Daniel T." <> wrote:
    > > > wrote:
    > > > > "Daniel T." <> wrote:
    > > > > > wrote:
    > > > > > > as this example,

    >
    > > > > > > question:

    >
    > > > > > > If my purpose is initialize data from xml files and store them in the
    > > > > > > vector, so they can be used in class B by other member functions, do
    > > > > > > you think functionP is a viable function(will a could go away after
    > > > > > > out of the function)?
    > > > > > > If not, is there a better solution than using functionPt?

    >
    > > > > > > I read that it is not a good design to have container for pointers(C++
    > > > > > > FAQs), but I cannot see how I can get around it in my situation..

    >
    > > > > > > Newbie questions, thanks for the help

    >
    > > > > > > Chris

    >
    > > > > > > class A{
    > > > > > >    ....
    > > > > > > }

    >
    > > > > > > class B{

    >
    > > > > > > void functionPt(){
    > > > > > >  ...
    > > > > > >   A* aPt ;

    >
    > > > > > aPt has not been initialized. Copying it into a vector is technically
    > > > > > undefined behavior.

    >
    > > > > > >   vPt.push_back(aPt);

    >
    > > > > > > }

    >
    > > > > > > void functionP(){
    > > > > > >   ...
    > > > > > >   A a;
    > > > > > >    v.push_back(a);
    > > > > > > }

    >
    > > > > > > private:
    > > > > > >    vector<A*> vPt;
    > > > > > >    vector<A>  v;

    >
    > > > > > > }

    >
    > > > > Thanks. My fault. My intention is A* aPt = new A;

    >
    > > > Now you have a leak.

    >
    > > not really. my ~B will iterate the vector and call delete.

    >
    > That's not in the code you posted though... You have to add it to the
    > code, also what about the copy constructor and the assignment operator?
    >
    > Once you take all of the above into account, and then compare the volume
    > of code you have to write in order to correctly implement the vector<A*>
    > solution, to how little you have to write to implement the vector<A>
    > solution, It is easy to see which is better.
    >
    > Let's look at the two with all these issues covered:
    >
    > class A { };
    >
    > class B1 {
    >    vector< A > vec;
    > public:
    >    void func() {
    >       vec.push_back( A() );
    >    }
    >
    > };
    >
    > verses:
    >
    >    // I may have missed some bits, but I think this is generally correct.
    > class B2 {
    >    vector< A* > vec;
    > public:
    >    B2( const B2& o ) : vec( o.vec.size() ) {
    >       try {
    >          vector< A* >::iterator o_it = o.vec.begin();
    >          for ( vector< A* >::iterator it = vec.begin();
    >                it != vec.end();
    >                ++it ) {
    >             *it = new A( *o_it );
    >             ++o_it;
    >          }
    >       }
    >       catch ( ... ) {
    >          for ( vector< A* >::iterator it = vec.begin();
    >                it != vec.end();
    >                ++it )
    >             delete *it;
    >          throw;
    >       }
    >    }
    >
    >    ~B2() {
    >       for ( vector< A* >::iterator it = vec.begin();
    >             it != vec.end();
    >             ++it )
    >          delete *it;
    >    }
    >
    >    void operator=( const B2& o ) {
    >       B2 tmp( o );
    >       swap( tmp.vec, vec );
    >    }
    >
    >    void func() {
    >       vec.push_back( new A );
    >    }
    >
    > };
    >
    > Why would you implement B2 if you didn't absolutely have to?


    Hi Daniel,

    Thank you very much for your advice. I totally agree with you that it
    is an awful idea to have pointers in container if I do not have to.
    The codes I posted is just to illustrate a scenario so I can clarify
    some fundamental concepts. I was wondering that if a local class
    variable's lifetime is within the method, the object may be gone after
    I go out of the method even after I put it in a member container
    variable, which may force me to use pointer instead of local object in
    the stack.

    As clarified by Ali, I will not bother to create pointers to store
    them in my vector at all.

    Thanks for your time

    Chris
     
    , Aug 7, 2008
    #8
    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. Xamalek
    Replies:
    7
    Views:
    708
  2. Vivi Orunitia
    Replies:
    11
    Views:
    4,544
    Martijn Lievaart
    Feb 4, 2004
  3. Maitre Bart
    Replies:
    2
    Views:
    550
    Maitre Bart
    Feb 11, 2004
  4. Marc Thrun
    Replies:
    15
    Views:
    884
    Tim Rentsch
    Oct 4, 2005
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    736
Loading...

Share This Page