Boost logo

Boost :

From: axter (boost_at_[hidden])
Date: 2006-01-04 08:57:43


"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";}
};

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;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk