$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Thorsten Ottosen (tottosen_at_[hidden])
Date: 2006-01-04 09:19:01
axter wrote:
> "Thorsten Ottosen" <tottosen_at_[hidden]> wrote in message
> news:<dpgi92$18k$1_at_[hidden]>...
> 
>>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