questions about pointers in container

T

tradevol

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;

}
 
A

acehreli

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
 
T

tradevol

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.



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


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
 
A

acehreli

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
 
T

tradevol

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top