Macro to contruct/allocate a shared_ptr?
I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far: #define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3)); --------------------------------- Example of usage for the type Test: class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} }; boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello"); --------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how many paramaters are in T's constructor. // not sure how to do this (or whether possible) // i am not sure how to implement the variable parameters // (hense the .. in my syntax) template <class T> boost::shared_ptr<T> New(...) { boost::shared_ptr<T> p(new T(...)); return p; } Any ideas? I often have problems with the c++ syntax when creating my own containers because i want to allocate T within the implementation (instead of passing pointers and having the user manage the memory).
What's wrong with boost::shared_ptr<Test> test( new Test ); boost::shared_ptr<Test> test( new Test( 100, 'a', "hello" ) ); http://boost.org/libs/smart_ptr/shared_ptr.htm I'm not sure how NEW0 or NEW or New is better than new... Making a macro that calls new doesn't encapsulate the call to new, it only obscures it and makes it less flexible. -----Original Message----- From: bringiton bringiton [mailto:kneeride@gmail.com] Sent: Thursday, July 13, 2006 6:38 PM To: boost-users@lists.boost.org Subject: [Boost-users] Macro to contruct/allocate a shared_ptr? I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far: #define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3)); --------------------------------- Example of usage for the type Test: class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} }; boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello"); --------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how many paramaters are in T's constructor. // not sure how to do this (or whether possible) // i am not sure how to implement the variable parameters // (hense the .. in my syntax) template <class T> boost::shared_ptr<T> New(...) { boost::shared_ptr<T> p(new T(...)); return p; } Any ideas? I often have problems with the c++ syntax when creating my own containers because i want to allocate T within the implementation (instead of passing pointers and having the user manage the memory). _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 7/14/06, Michael Nicolella
What's wrong with
boost::shared_ptr<Test> test( new Test ); boost::shared_ptr<Test> test( new Test( 100, 'a', "hello" ) );
http://boost.org/libs/smart_ptr/shared_ptr.htm
I'm not sure how NEW0 or NEW or New is better than new... Making a macro that calls new doesn't encapsulate the call to new, it only obscures it and makes it less flexible.
-----Original Message----- From: bringiton bringiton [mailto:kneeride@gmail.com] Sent: Thursday, July 13, 2006 6:38 PM To: boost-users@lists.boost.org Subject: [Boost-users] Macro to contruct/allocate a shared_ptr?
I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far:
#define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3));
--------------------------------- Example of usage for the type Test:
class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} };
boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello");
--------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how many paramaters are in T's constructor.
// not sure how to do this (or whether possible) // i am not sure how to implement the variable parameters // (hense the .. in my syntax) template <class T> boost::shared_ptr<T> New(...) { boost::shared_ptr<T> p(new T(...)); return p; }
Any ideas? I often have problems with the c++ syntax when creating my own containers because i want to allocate T within the implementation (instead of passing pointers and having the user manage the memory). _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I just have a problem with having the user manage the memory. ie I'd rather do the following: shared_ptr<Test> p(1, 'a', "hello"); or: shared_ptr<Test> p = newptr<Test>(1, 'a', "hello"); instead of: shared_ptr<Test> p(new p(1, 'a', "hello")); but i guess that's a limitation of the language. to get around this i do the following: class Test { private: Test(int p1, char p2, string p3) {;} public: static shared_ptr<Test> NewTest(int p1, char p2, string p3) { return p(new Test(p1, p2, p3); } ... // memory allocation hidden shared_ptr<Test> t = Test::NewTest(1, 'a', "hello"); but this is a hassle. esp when many constructors...
bringiton bringiton
On 7/14/06, Michael Nicolella
wrote: What's wrong with
boost::shared_ptr<Test> test( new Test ); boost::shared_ptr<Test> test( new Test( 100, 'a', "hello" ) );
http://boost.org/libs/smart_ptr/shared_ptr.htm
I'm not sure how NEW0 or NEW or New is better than new... Making a macro that calls new doesn't encapsulate the call to new, it only obscures it and makes it less flexible.
-----Original Message----- From: bringiton bringiton [mailto:kneeride <at> gmail.com] Sent: Thursday, July 13, 2006 6:38 PM To: boost-users <at> lists.boost.org Subject: [Boost-users] Macro to contruct/allocate a shared_ptr?
I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far:
#define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3));
--------------------------------- Example of usage for the type Test:
class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} };
boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello");
--------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how
many
paramaters are in T's constructor.
// not sure how to do this (or whether possible) // i am not sure how to implement the variable parameters // (hense the .. in my syntax) template <class T> boost::shared_ptr<T> New(...) { boost::shared_ptr<T> p(new T(...)); return p; }
Any ideas? I often have problems with the c++ syntax when creating my own containers because i want to allocate T within the implementation (instead of passing pointers and having the user manage the memory). _______________________________________________ Boost-users mailing list Boost-users <at> lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users <at> lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I just have a problem with having the user manage the memory. ie I'd rather do the following:
shared_ptr<Test> p(1, 'a', "hello"); or: shared_ptr<Test> p = newptr<Test>(1, 'a', "hello");
instead of:
shared_ptr<Test> p(new p(1, 'a', "hello"));
but i guess that's a limitation of the language. to get around this i do the following:
class Test { private: Test(int p1, char p2, string p3) {;} public: static shared_ptr<Test> NewTest(int p1, char p2, string p3) { return p(new Test(p1, p2, p3); } ...
// memory allocation hidden shared_ptr<Test> t = Test::NewTest(1, 'a', "hello");
but this is a hassle. esp when many constructors...
You can try this:
#include
Thanks Roman.
so is this how i would use your implementation?
boost::shared_ptr<Test> t = newptr
bringiton bringiton
writes: On 7/14/06, Michael Nicolella
wrote: What's wrong with
boost::shared_ptr<Test> test( new Test ); boost::shared_ptr<Test> test( new Test( 100, 'a', "hello" ) );
http://boost.org/libs/smart_ptr/shared_ptr.htm
I'm not sure how NEW0 or NEW or New is better than new... Making a macro that calls new doesn't encapsulate the call to new, it only obscures it and makes it less flexible.
-----Original Message----- From: bringiton bringiton [mailto:kneeride <at> gmail.com] Sent: Thursday, July 13, 2006 6:38 PM To: boost-users <at> lists.boost.org Subject: [Boost-users] Macro to contruct/allocate a shared_ptr?
I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far:
#define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3));
--------------------------------- Example of usage for the type Test:
class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} };
boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello");
--------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how
many
paramaters are in T's constructor.
// not sure how to do this (or whether possible) // i am not sure how to implement the variable parameters // (hense the .. in my syntax) template <class T> boost::shared_ptr<T> New(...) { boost::shared_ptr<T> p(new T(...)); return p; }
Any ideas? I often have problems with the c++ syntax when creating my own containers because i want to allocate T within the implementation (instead of passing pointers and having the user manage the memory). _______________________________________________ Boost-users mailing list Boost-users <at> lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users <at> lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I just have a problem with having the user manage the memory. ie I'd rather do the following:
shared_ptr<Test> p(1, 'a', "hello"); or: shared_ptr<Test> p = newptr<Test>(1, 'a', "hello");
instead of:
shared_ptr<Test> p(new p(1, 'a', "hello"));
but i guess that's a limitation of the language. to get around this i do the following:
class Test { private: Test(int p1, char p2, string p3) {;} public: static shared_ptr<Test> NewTest(int p1, char p2, string p3) { return p(new Test(p1, p2, p3); } ...
// memory allocation hidden shared_ptr<Test> t = Test::NewTest(1, 'a', "hello");
but this is a hassle. esp when many constructors...
You can try this:
#include
template <class R> boost::shared_ptr<R> newptr() { return boost::shared_ptr<R>(new R()); }
template
boost::shared_ptr<R> newptr(T0 p0) { return boost::shared_ptr<R>(new R(p0)); } template
boost::shared_ptr<R> newptr(T0 p0, T1 p1) { return boost::shared_ptr<R>(new R(p0, p1)); } // and so on...
Also you can generate newptr functions with the boost preprocessor library.
#include
#define BOOST_PP_LOCAL_MACRO(N)\ template
\ boost::shared_ptr<R> newptr(BOOST_PP_ENUM_BINARY_PARAMS(N, T, p))\ {\ return boost::shared_ptr<R>(new R(BOOST_PP_ENUM_PARAMS(N, p)));\ } #define BOOST_PP_LOCAL_LIMITS (0, 10) #include BOOST_PP_LOCAL_ITERATE()
Now you can use newptr with by up to 10 arguments.
HTH, Roman Perepelitsa.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
bringiton> I'm trying to define a MACRO that creates a shared_ptr and hides bringiton> memory allocation. Here is what i have so far: bringiton> #define NEW0(T) boost::shared_ptr<T>(new T()); bringiton> #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); bringiton> #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); bringiton> #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3)); There is something wrong in the idea. I mean from the design point of view. I think you should either trust your users to know enough about shared pointers so as not to screw up memory allocation (I am paranoid in this regard too though :)). Or you should hide the shared pointer altogether. So this:
boost::shared_ptr<Test> p0 = NEW0(Test);
Will become something like this (and make all the constructors private): Test::Ptr p0 = Test::Allocate(); That requires more work, but it does fully enforce the contract. If you maintain that consistently, throughout all you code, you will have the control you desire. Down to transparent use of custom allocators. A wrapper (macro or else) just to ease the use of shared pointers is pointless, since it does nothing to force its usage, and more often than not, you will see it bypassed because of some momentary inconvenience. Then, all of a sudden, you decide to allocate memory on a user's newly installed brain implant (instead of old microchip), you modify you macro or whatnot to use custom allocators (since new/delete used by shared pointer are working with the old one), but in all the weird places it would not be used. The head will explode then. That is, however you do it, there should be either total freedom or total control.
On 7/15/06, Zolenko Yevgeniy
bringiton> I'm trying to define a MACRO that creates a shared_ptr and hides bringiton> memory allocation. Here is what i have so far:
bringiton> #define NEW0(T) boost::shared_ptr<T>(new T()); bringiton> #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); bringiton> #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); bringiton> #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3));
There is something wrong in the idea.
I mean from the design point of view. I think you should either trust your users to know enough about shared pointers so as not to screw up memory allocation (I am paranoid in this regard too though :)). Or you should hide the shared pointer altogether.
So this:
boost::shared_ptr<Test> p0 = NEW0(Test);
Will become something like this (and make all the constructors private):
Test::Ptr p0 = Test::Allocate();
That requires more work, but it does fully enforce the contract.
If you maintain that consistently, throughout all you code, you will have the control you desire. Down to transparent use of custom allocators.
A wrapper (macro or else) just to ease the use of shared pointers is pointless, since it does nothing to force its usage, and more often than not, you will see it bypassed because of some momentary inconvenience.
Then, all of a sudden, you decide to allocate memory on a user's newly installed brain implant (instead of old microchip), you modify you macro or whatnot to use custom allocators (since new/delete used by shared pointer are working with the old one), but in all the weird places it would not be used. The head will explode then.
That is, however you do it, there should be either total freedom or total control.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
i disagree. The aim of c++ is to hide implementation details. ie std::vector hides array memory management, std::list hides linked list implementation. i think it defeats the purpose of having a memory management class where the user manages the memory. i can see all sorts of problems with the following: shared_ptr<int> p(new int(1)); for example: int x = new int(1); shared_ptr<int> p(v); shared_ptr<int> q(v); // OUCH!!!! i don't want to assume that users will use the interface correctly. if i have a choice, i'd rather make the interface bulletproof. i've made a shared_ptr wrapper. it is very strict how it manages memory + the user can not break it. object<int> o; o.NewObject(1); object<string> o; o.NewObject("hello"); object<Test> o; o.NewObject(1, 'a', "hello");
there should be either total freedom or total control.
i dissagree again. ok, stl and boost need to be very generic because it needs to be used in many types evironments/programs. however, for my needs, i am writing 1 program in particular, and would like my objects to behave only in a manner that is appropriate for that program.
There is something wrong in the idea.
bringiton> i disagree. The aim of c++ is to hide implementation details. ie bringiton> std::vector hides array memory management, std::list hides linked list bringiton> implementation. Yep. And they hide it completely (supposed to at least). bringiton> i think it defeats the purpose of having a memory management class bringiton> where the user manages the memory. i can see all sorts of problems bringiton> with the following: True. If you use any kind of weak contract, that's what you eventually get. (By weak I mean not enforced by compiler, or at worst -- runtime). bringiton> i don't want to assume that users will use the interface correctly. if bringiton> i have a choice, i'd rather make the interface bulletproof. bringiton> i've made a shared_ptr wrapper. it is very strict how it manages bringiton> memory + the user can not break it. Yes, so you went by the path of total control. I don't know how you did it, but first simplest thing that comes in my mind is something like that (the class itself controls its allocating): class Test { public: typedef shared_ptr<Test> Ptr; static Ptr Allocate() { return Ptr(new Test()); } private: Test() {} }; From here what user can pretty much do is just follow you way: Test::Ptr test = Test::Allocate(); Things like those will fail at compile time: Test test; Test* test = new Test(); ((Test*)malloc(sizeof(Test)) will still work though, but that will be useless if there is some initialization to do) bringiton> object<Test> o; bringiton> o.NewObject(1, 'a', "hello"); Well, for this to work you object<> has to be like a transparent proxy. As long as users can't allocate whatever classes you use, or can't use them with your code unless allocated like that -- it will work good.
there should be either total freedom or total control.
bringiton> i dissagree again. ok, stl and boost need to be very generic because bringiton> it needs to be used in many types evironments/programs. bringiton> however, for my needs, i am writing 1 program in particular, and would bringiton> like my objects to behave only in a manner that is appropriate for bringiton> that program. Yep, so you went the second road. Just don't stop halfway :). If user can't normally break it -- you are fine.
On 7/16/06, Zolenko Yevgeniy
There is something wrong in the idea.
bringiton> i disagree. The aim of c++ is to hide implementation details. ie bringiton> std::vector hides array memory management, std::list hides linked list bringiton> implementation.
Yep. And they hide it completely (supposed to at least).
bringiton> i think it defeats the purpose of having a memory management class bringiton> where the user manages the memory. i can see all sorts of problems bringiton> with the following:
True. If you use any kind of weak contract, that's what you eventually get. (By weak I mean not enforced by compiler, or at worst -- runtime).
bringiton> i don't want to assume that users will use the interface correctly. if bringiton> i have a choice, i'd rather make the interface bulletproof.
bringiton> i've made a shared_ptr wrapper. it is very strict how it manages bringiton> memory + the user can not break it.
Yes, so you went by the path of total control. I don't know how you did it, but first simplest thing that comes in my mind is something like that (the class itself controls its allocating):
class Test { public: typedef shared_ptr<Test> Ptr;
static Ptr Allocate() { return Ptr(new Test()); } private: Test() {} };
From here what user can pretty much do is just follow you way: Test::Ptr test = Test::Allocate();
Things like those will fail at compile time: Test test; Test* test = new Test();
((Test*)malloc(sizeof(Test)) will still work though, but that will be useless if there is some initialization to do)
bringiton> object<Test> o; bringiton> o.NewObject(1, 'a', "hello");
Well, for this to work you object<> has to be like a transparent proxy. As long as users can't allocate whatever classes you use, or can't use them with your code unless allocated like that -- it will work good.
there should be either total freedom or total control.
bringiton> i dissagree again. ok, stl and boost need to be very generic because bringiton> it needs to be used in many types evironments/programs.
bringiton> however, for my needs, i am writing 1 program in particular, and would bringiton> like my objects to behave only in a manner that is appropriate for bringiton> that program.
Yep, so you went the second road. Just don't stop halfway :). If user can't normally break it -- you are fine.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Yes Zolenko, that is what I was trying to say. To try and design so
that the compiler detects all misuse of the interface.
Initially my shared pointers that encapsulated memory managent could
only use the default contructor of T. ie:
template <class T>
class Ptr {
void Allocate() {
ptr.reset(new T());
}
With the help of Roman, the class can now handle other constuctors.
// 0 parameter
void NewObject() {
m_ptr.reset(new TTYPE());
}
// 1 parameter
template <class P1>
void NewObject(P1 p1) {
m_ptr.reset(new TTYPE(p1));
}
// 2 parameters
template
bringiton> Initially my shared pointers that encapsulated memory managent could bringiton> only use the default contructor of T. ie: bringiton> template <class T> bringiton> class Ptr { bringiton> void Allocate() { bringiton> ptr.reset(new T()); bringiton> } Ah, I see. So in your other code, where you need the pointer to a class you manage, you accept a specialized wrapper of this class? That is you, always pass pointers around like that: void SetTestPointer(Ptr<Test> test); And not unwrapped shared_ptrs for example. PS You can do reset() in the constructor of the wrapper (or was it just an example?) Like that you separate allocation from initialization, and that is just more work for users (unless you need it for some reason).
You can do reset() in the constructor of the wrapper (or was it just an example?)
yes just an example. however that is how i have it at the moment. i was thinking about doing allocation in the constructor, but this opens too much confusion because it would be unclear via the interface whether the default contructor would 1. allocate a null/empty shared_ptr, or 2. allocate a default object. ie Ptr<Test> p(1, 'a', "hello"); // OK, object created Ptr<Test> p2; // ??? unclear if default object allocated or null pointer I think the best way around this would be to have a static function create a pointer and treat the declaration with initialisation syntax. eg Ptr<Test> p; // null object Ptr<Test> p2 = Ptr<Test>::New(); // default object allocated Ptr<Test> p3 = Ptr<Test>::New(1, 'a', "hello"); // object allocated What are your thoughts Evgeniy? i'm hoping the compiler would be able to optimise the above. ie use copy constructor instead of default constructor + operator=(). maybe even realise that only 1 object needs to be created. **but i dont know much about this area
bringiton> i was thinking about doing allocation in the constructor, but this bringiton> opens too much confusion because it would be unclear via the interface bringiton> whether the default contructor would 1. allocate a null/empty bringiton> shared_ptr, or 2. allocate a default object. ie If you have null wrapper object, you have to have a way to reset it and a way to check for nullness. Also, unless null objects will be used often enough, it might be better to move creation of null wrapper into a static function (and leave constructors to do the resets) Ptr<Test> p(Ptr<Test>::Null()); Have a private constructor that will accept pointer to managed class (just for signature, you will never need it normally anyway), and call it with NULL. template<class T> class Ptr { public: Prt() { m_ptr.reset(new T()); } static Ptr<T> Null() { return Ptr<T>((T*)NULL); } private: shared_ptr<T> m_ptr; Ptr(T* t) { } }; bringiton> Ptr<Test> p(1, 'a', "hello"); // OK, object created bringiton> Ptr<Test> p2; // ??? unclear if default object allocated or null pointer You have to document it once :). And having an explicit way of creating null wrappers is pretty self explanatory. bringiton> i'm hoping the compiler would be able to optimise the above. ie use bringiton> copy constructor instead of default constructor + operator=(). maybe bringiton> even realise that only 1 object needs to be created. **but i dont know bringiton> much about this area Yep, it will be done through copy constructor.
interesting idea having default contructor create a default object Ptr<Test> p1; // default object allocted Ptr<Test> p2(1, 'a', "hello"); Ptr<Test> p3(Ptr<Text>::Null()); // null object p1 = Ptr<Text>::Null(); // reset to null I could even consider an object that can never be null. It would work like a reference counting reference (instead of reference counting pointer). it would also be unbreakable. ie no null missuse. and then as a rule, if more flexibility is needed, then use the shared_ptr interface instead
"bringiton bringiton"
I'm trying to define a MACRO that creates a shared_ptr and hides memory allocation. Here is what i have so far:
#define NEW0(T) boost::shared_ptr<T>(new T()); #define NEW1(T, p1) boost::shared_ptr<T>(new T(p1)); #define NEW2(T, p1, p2) boost::shared_ptr<T>(new T(p1, p2)); #define NEW3(T, p1, p2, p3) boost::shared_ptr<T>(new T(p1, p2, p3));
--------------------------------- Example of usage for the type Test:
class Test { public: Test() {;} Test(int p1) {;} Test(int p1, char p2) {;} Test(int p1, char p2, std::string p3) {;} };
boost::shared_ptr<Test> p0 = NEW0(Test); boost::shared_ptr<Test> p1 = NEW1(Test, 100); boost::shared_ptr<Test> p2 = NEW2(Test, 100, 'a'); boost::shared_ptr<Test> p3 = NEW3(Test, 100, 'a', "hello");
--------------------------------- Is there a better way to do this? I would prefer to use a function instead of a MACRO. But I don't think it is possible because it is not know how many paramaters are in T's constructor.
The basic intention is sound, but there are better ways to do it, that don't involve macros (for the user): http://article.gmane.org/gmane.comp.lib.boost.devel/140159 -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (6)
-
bringiton bringiton
-
David Abrahams
-
Evgeniy Zolenko
-
Michael Nicolella
-
Roman Perepelitsa
-
Zolenko Yevgeniy