shared_ptr_basic_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 300 行

CPP
300
字号
#include <boost/config.hpp>#if defined(BOOST_MSVC)#pragma warning(disable: 4786)  // identifier truncated in debug info#pragma warning(disable: 4710)  // function not inlined#pragma warning(disable: 4711)  // function selected for automatic inline expansion#pragma warning(disable: 4514)  // unreferenced inline removed#pragma warning(disable: 4355)  // 'this' : used in base member initializer list#if (BOOST_MSVC >= 1310)#pragma warning(disable: 4675)  // resolved overload found with Koenig lookup#endif#endif////  shared_ptr_basic_test.cpp////  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//#include <boost/detail/lightweight_test.hpp>#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>int cnt = 0;struct X{    X()    {        ++cnt;    }    ~X() // virtual destructor deliberately omitted    {        --cnt;    }    virtual int id() const    {        return 1;    }private:    X(X const &);    X & operator= (X const &);};struct Y: public X{    Y()    {        ++cnt;    }    ~Y()    {        --cnt;    }    virtual int id() const    {        return 2;    }private:    Y(Y const &);    Y & operator= (Y const &);};int * get_object(){    ++cnt;    return &cnt;}void release_object(int * p){    BOOST_TEST(p == &cnt);    --cnt;}template<class T> void test_is_X(boost::shared_ptr<T> const & p){    BOOST_TEST(p->id() == 1);    BOOST_TEST((*p).id() == 1);}template<class T> void test_is_X(boost::weak_ptr<T> const & p){    BOOST_TEST(p.get() != 0);    BOOST_TEST(p.get()->id() == 1);}template<class T> void test_is_Y(boost::shared_ptr<T> const & p){    BOOST_TEST(p->id() == 2);    BOOST_TEST((*p).id() == 2);}template<class T> void test_is_Y(boost::weak_ptr<T> const & p){    boost::shared_ptr<T> q = p.lock();    BOOST_TEST(q.get() != 0);    BOOST_TEST(q->id() == 2);}template<class T> void test_eq(T const & a, T const & b){    BOOST_TEST(a == b);    BOOST_TEST(!(a != b));    BOOST_TEST(!(a < b));    BOOST_TEST(!(b < a));}template<class T> void test_ne(T const & a, T const & b){    BOOST_TEST(!(a == b));    BOOST_TEST(a != b);    BOOST_TEST(a < b || b < a);    BOOST_TEST(!(a < b && b < a));}template<class T, class U> void test_shared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b){    BOOST_TEST(!(a < b));    BOOST_TEST(!(b < a));}template<class T, class U> void test_nonshared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b){    BOOST_TEST(a < b || b < a);    BOOST_TEST(!(a < b && b < a));}template<class T, class U> void test_eq2(T const & a, U const & b){    BOOST_TEST(a == b);    BOOST_TEST(!(a != b));}template<class T, class U> void test_ne2(T const & a, U const & b){    BOOST_TEST(!(a == b));    BOOST_TEST(a != b);}template<class T> void test_is_zero(boost::shared_ptr<T> const & p){    BOOST_TEST(!p);    BOOST_TEST(p.get() == 0);}template<class T> void test_is_nonzero(boost::shared_ptr<T> const & p){    // p? true: false is used to test p in a boolean context.    // BOOST_TEST(p) is not guaranteed to test the conversion,    // as the macro might test !!p instead.    BOOST_TEST(p? true: false);    BOOST_TEST(p.get() != 0);}int main(){    using namespace boost;    {        shared_ptr<X> p(new Y);        shared_ptr<X> p2(new X);        test_is_nonzero(p);        test_is_nonzero(p2);        test_is_Y(p);        test_is_X(p2);        test_ne(p, p2);        {            shared_ptr<X> q(p);            test_eq(p, q);        }        shared_ptr<Y> p3 = dynamic_pointer_cast<Y>(p);        shared_ptr<Y> p4 = dynamic_pointer_cast<Y>(p2);        test_is_nonzero(p3);        test_is_zero(p4);        BOOST_TEST(p.use_count() == 2);        BOOST_TEST(p2.use_count() == 1);        BOOST_TEST(p3.use_count() == 2);        test_is_Y(p3);        test_eq2(p, p3);        test_ne2(p2, p4);        shared_ptr<void> p5(p);        test_is_nonzero(p5);        test_eq2(p, p5);        weak_ptr<X> wp1(p2);        BOOST_TEST(!wp1.expired());        BOOST_TEST(wp1.use_count() != 0);        p.reset();        p2.reset();        p3.reset();        p4.reset();        test_is_zero(p);        test_is_zero(p2);        test_is_zero(p3);        test_is_zero(p4);        BOOST_TEST(p5.use_count() == 1);        BOOST_TEST(wp1.expired());        BOOST_TEST(wp1.use_count() == 0);        try        {            shared_ptr<X> sp1(wp1);            BOOST_ERROR("shared_ptr<X> sp1(wp1) failed to throw");        }        catch(boost::bad_weak_ptr const &)        {        }        test_is_zero(wp1.lock());        weak_ptr<X> wp2 = static_pointer_cast<X>(p5);        BOOST_TEST(wp2.use_count() == 1);        test_is_Y(wp2);        test_nonshared(wp1, wp2);        // Scoped to not affect the subsequent use_count() tests.        {            shared_ptr<X> sp2(wp2);            test_is_nonzero(wp2.lock());        }        weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock());        BOOST_TEST(wp3.use_count() == 1);        test_shared(wp2, wp3);        weak_ptr<X> wp4(wp3);        BOOST_TEST(wp4.use_count() == 1);        test_shared(wp2, wp4);        wp1 = p2;        test_is_zero(wp1.lock());        wp1 = p4;        wp1 = wp3;        wp1 = wp2;        BOOST_TEST(wp1.use_count() == 1);        test_shared(wp1, wp2);        weak_ptr<X> wp5;        bool b1 = wp1 < wp5;        bool b2 = wp5 < wp1;        p5.reset();        BOOST_TEST(wp1.use_count() == 0);        BOOST_TEST(wp2.use_count() == 0);        BOOST_TEST(wp3.use_count() == 0);        // Test operator< stability for std::set< weak_ptr<> >        // Thanks to Joe Gottman for pointing this out        BOOST_TEST(b1 == (wp1 < wp5));        BOOST_TEST(b2 == (wp5 < wp1));        {            // note that both get_object and release_object deal with int*            shared_ptr<void> p6(get_object(), release_object);        }    }    BOOST_TEST(cnt == 0);    return boost::report_errors();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?