Re: [boost] ptr_container: ptr_map_adapter interface

"Thorsten Ottosen" <tottosen@dezide.com> wrote in message news:<dpgi92$18k$1@sea.gmane.org>...
axter wrote:
The pointer-containers don't slica anything on their own. If you insist on not making your class hierarchy non-copyable, I can't help you.
I don't see that making a difference, but could you please post a small example class that is non-copyable, so that I can test it out.
struct Foo { private: Foo( const Foo& ); Foo& operator=( const Foo& ); };
or
#include <boost/utility.hpp>
struct Bar : boost::noncopyable { };
In addition, an explicit copy-constructor will prohibit slicing on compliant compilers.
No, it doesn't. That's what I thought you where talking about, but I wanted to make sure before possibly putting my foot in my mouth. Both the above methods prevent slicing of concrete types. However, it does not prevent slicing in pointer idiom. See following example code using booost::ptr_vector, and non-copyable types that get slice, where BasesS1 uses the first non-copyable method, and BasesS2 uses the boost::noncopyable method. Both end up getting slice when the container gets copied. class BasesS1 { public: virtual BasesS1* do_clone()const=0; virtual string WhoAmI()const=0; BasesS1(int i = 0):m_i(i){} private: BasesS1( const BasesS1& ); BasesS1& operator=( const BasesS1& ); protected: int m_i; }; class DerivedS1 : public BasesS1 { public: DerivedS1(int i = 0):BasesS1(i){} BasesS1* do_clone()const{return new DerivedS1();} string WhoAmI()const{return "DerivedS1";} }; class DerivedDerivedS1 : public DerivedS1 { public: DerivedDerivedS1(int i = 0):DerivedS1(i){} string WhoAmI()const{return "DerivedDerivedS1";} }; inline BasesS1* new_clone( const BasesS1& a ) { return a.do_clone(); } class BasesS2 : boost::noncopyable { public: virtual BasesS2* do_clone()const=0; virtual string WhoAmI()const=0; BasesS2(int i = 0):m_i(i){} protected: int m_i; }; class DerivedS2 : public BasesS2 { public: DerivedS2(int i = 0):BasesS2(i){} BasesS2* do_clone()const{return new DerivedS2();} string WhoAmI()const{return "DerivedS2";} }; class DerivedDerivedS2 : public DerivedS2 { public: DerivedDerivedS2(int i = 0):DerivedS2(i){} string WhoAmI()const{return "DerivedDerivedS2";} }; inline BasesS2* new_clone( const BasesS2& a ) { return a.do_clone(); } int main(int, char**) { boost::ptr_vector<BasesS1> vBaseS1_cpy1; vBaseS1_cpy1.push_back(new DerivedDerivedS1(123)); boost::ptr_vector<BasesS1> vBaseS1_cpy2(vBaseS1_cpy1.begin(), vBaseS1_cpy1.end()); cout << vBaseS1_cpy2[0].WhoAmI() << endl; boost::ptr_vector<BasesS2> vBaseS2_cpy1; vBaseS2_cpy1.push_back(new DerivedDerivedS2(123)); boost::ptr_vector<BasesS2> vBaseS2_cpy2(vBaseS2_cpy1.begin(), vBaseS2_cpy1.end()); cout << vBaseS2_cpy2[0].WhoAmI() << endl;

axter wrote:
"Thorsten Ottosen" <tottosen@dezide.com> wrote in message news:<dpgi92$18k$1@sea.gmane.org>...
axter wrote:
The pointer-containers don't slica anything on their own. If you insist on not making your class hierarchy non-copyable, I can't help you.
I don't see that making a difference, but could you please post a small example class that is non-copyable, so that I can test it out.
struct Foo { private: Foo( const Foo& ); Foo& operator=( const Foo& ); };
or
#include <boost/utility.hpp>
struct Bar : boost::noncopyable { };
In addition, an explicit copy-constructor will prohibit slicing on compliant compilers.
No, it doesn't. That's what I thought you where talking about, but I wanted to make sure before possibly putting my foot in my mouth.
Both the above methods prevent slicing of concrete types. However, it does not prevent slicing in pointer idiom. See following example code using booost::ptr_vector, and non-copyable types that get slice, where BasesS1 uses the first non-copyable method, and BasesS2 uses the boost::noncopyable method. Both end up getting slice when the container gets copied.
class BasesS1 { public: virtual BasesS1* do_clone()const=0; virtual string WhoAmI()const=0; BasesS1(int i = 0):m_i(i){} private: BasesS1( const BasesS1& ); BasesS1& operator=( const BasesS1& ); protected: int m_i; };
class DerivedS1 : public BasesS1 { public: DerivedS1(int i = 0):BasesS1(i){} BasesS1* do_clone()const{return new DerivedS1();} string WhoAmI()const{return "DerivedS1";} };
class DerivedDerivedS1 : public DerivedS1 { public: DerivedDerivedS1(int i = 0):DerivedS1(i){} string WhoAmI()const{return "DerivedDerivedS1";} };
[snip]
int main(int, char**) { boost::ptr_vector<BasesS1> vBaseS1_cpy1; vBaseS1_cpy1.push_back(new DerivedDerivedS1(123)); boost::ptr_vector<BasesS1> vBaseS1_cpy2(vBaseS1_cpy1.begin(), vBaseS1_cpy1.end()); cout << vBaseS1_cpy2[0].WhoAmI() << endl;
Note that DerivedDerivedS1/S2 does not implement do_clone(). -Thorsten
participants (2)
-
axter
-
Thorsten Ottosen