shared_ptr/shared_array Question
I downloaded yesterday the boost libraries (mainly for the memory libs) and to tell the truth i'm impressed with pool and smart pointers. Especially the boost smart pointers will save me from months of coding! However i have a question about smart pointers. Let's say i have these objects(the code is just an example): class Slave { Slave(); ~Slave(); }; class Master { Master(); Master(int size); ~Master(); Slave *sl; }; I want "sl" to be an array of Slaves on the free store but the sized will be determined in the constructor. With normal pointers i would write: Master::Master(int val) { sl=new Slave[val]; } Master::~Master() { delete sl; } How can i achieve the same with boost smart pointers? I've read the manual three or four times but i still don't get how to work this out. Does this have something to do with the empty ptr? I believe solution is in front of my eyes but i'm too blind(as usual) to see it...
On Feb 25, 2004, at 12:27 PM, voodoo4 wrote:
I downloaded yesterday the boost libraries (mainly for the memory libs) and to tell the truth i'm impressed with pool and smart pointers. Especially the boost smart pointers will save me from months of coding! However i have a question about smart pointers.
Let's say i have these objects(the code is just an example):
class Slave { Slave(); ~Slave(); };
class Master { Master(); Master(int size); ~Master();
Slave *sl; };
I want "sl" to be an array of Slaves on the free store but the sized will be determined in the constructor.
With normal pointers i would write:
Master::Master(int val) { sl=new Slave[val]; }
Master::~Master() { delete sl; }
How can i achieve the same with boost smart pointers?
I have no idea (see below).
I've read the manual three or four times but i still don't get how to work this out. Does this have something to do with the empty ptr? I believe solution is in front of my eyes but i'm too blind(as usual) to see it...
I don't think you're using the right tool for the job. From what I know, smart pointers should be used when you have one object, here you (potentially) have many. I think what you really want to do here is to use a container class like stl::list or stl::vector to contain your slave objects. If you still want to use smart pointers, I guess you could use a list of smart pointers, but there's really no point for that if your slave class is properly coded (for instance, has a ctor, copy ctor, virtual dtor, and operator=). --MP
*GoochRules wrote:*
I don't think you're using the right tool for the job. From what I know, smart pointers should be used when you have one object, here you (potentially) have many. I think what you really want to do here is to use a container class like stl::list or stl::vector to contain your slave objects.
If you still want to use smart pointers, I guess you could use a list of smart pointers, but there's really no point for that if your slave class is properly coded (for instance, has a ctor, copy ctor, virtual dtor, and operator=).
The slave and master classes are just example code i wrote in my mail to describe my question. I need smart pointers for memory managment in a game i'm coding and it would be a pain in the ass to code the whole thing from scratch.Shared_ptr and shared_array will save me a lot of time. *Colin Rafferty wrote:*
class Master { // ... shared_array<Slave> sl; };
Master::Master(int val) : sl(new Slave[val]) { }
Master::~Master() { // intentionally left blank! }
It works.Thanks! However i'm still having a problem understanding how i'm going to initialize the Slave array in some other function rather than in initialization, and keep the scope public for the whole Master object(excuse my terminology,i'm not english).
Of course, you may want to use scoped_array<Slave> instead of shared_array<Slave>, but that depends on what you want to do.
No.scoped_ptr and scoped_array cannot be used in STL containers and of course the pointed object cannot be shared among pointers. *Mark Storer wrote*
I'd go with scoped_array<> by default, and only go with shared_array<> if you need to share OWNERSHIP of that array. This master/slave example doesn't give enough context to make the choice apparent.
PS: There's a bug in your original code:
Master::~Master() { delete sl; }
If you use the [] version of new, you should use the [] version of delete:
Master::~Master() { delete[] sl; } Otherwise, many implementations of 'delete' will only call the destructor of the first element in the array, and may or may not free up the entire block of memory. Some implementations may actually clean everything up properly, but I wouldn't count on it if I were you.
I took for granted that you would understand the code i wrote in this mail only intended to describe my problem. I guess it's my mistake that i didn't make it clear. Anyway Mark in my real program i need to share ownership of my objects(see replies above) and you're right in what you're saying about the mistake. It's just a typo but it could be a killer bug! There are little chances your program recovers from such a bug. I'm impressed how fast people replied to my question.It's a really vivid community Sorry for the long post
voodoo4@otenet.gr wrote:
Colin Rafferty wrote:
class Master { // ... shared_array<Slave> sl; };
Master::Master(int val) : sl(new Slave[val]) { }
Master::~Master() { // intentionally left blank! }
It works.Thanks! However i'm still having a problem understanding how i'm going to initialize the Slave array in some other function rather than in initialization, and keep the scope public for the whole Master object(excuse my terminology,i'm not english).
Just like initializing anything else in a different function. extern shared_array<Slave> createSharedArray(); Master::Master(int val) : sl(::createSharedArray()) { } -- Colin
*Colin Rafferty wrote:*
Just like initializing anything else in a different function.
extern shared_array<Slave> createSharedArray();
Master::Master(int val) : sl(::createSharedArray()) { }
Well it is not what i meant but it doesn't really matter cause i solved my problem. I just had to do a simple cast...Duh! And for anyone interested: //A macro to to shorten the shared_array template code.Not really strong typed... #define SM_A(x) boost::shared_array<x> class Slave { Slave(){ }; ~Slave(){ }; }; class Master { public: Master(){ }; ~Master(){ }; void SomeFunction(int val){ sl = SM_A(Slave)(new sl[val];}; SM_A(Slave) sl; }; As i suspected.I'm an idiot who's bothering other people with his ridiculous problems... Thanks for your replies.
voodoo4@otenet.gr wrote:
Let's say i have these objects(the code is just an example):
class Slave { Slave(); ~Slave(); };
class Master { Master(); Master(int size); ~Master();
Slave *sl; };
I want "sl" to be an array of Slaves on the free store but the sized will be determined in the constructor.
With normal pointers i would write:
Master::Master(int val) { sl=new Slave[val]; }
Master::~Master() { delete sl; }
class Master { // ... shared_array<Slave> sl; }; Master::Master(int val) : sl(new Slave[val]) { } Master::~Master() { // intentionally left blank! } Of course, you may want to use scoped_array<Slave> instead of shared_array<Slave>, but that depends on what you want to do. -- Colin
participants (3)
-
Colin Rafferty
-
GoochRules!
-
voodoo4