|
Boost : |
From: David Maisonave (dmaisonave_at_[hidden])
Date: 2006-01-04 10:51:04
"Thorsten Ottosen" <tottosen_at_[hidden]> wrote in message
news:<dpglgo$cb1$1_at_[hidden]>...
> 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().
>
Yes. That's exactly the point I'm trying to make.
Both the boost pointer containers and the cow_ptr/copy_ptr method can
result in splicing via improper usage.
Both methods can produce splicing via derive-derive type, and both
methods can produce splicing via derive type of a non-abstract type.
Furthermore, making the class non-copyable does not prevent the splicing
in a pointer idiom.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk