开发者

Can you give me an example when auto_ptr_ref is really necessary?

I would like to understand better the mechanics and the issues behind creating library and I have decided to start from the std::auto_ptr. I am familiar with the syntax and the usage, however I am trying to understand the i开发者_开发问答mplementation details. I have implemented my version of the auto_ptr and it looks like this:

#ifndef _AUTO_PTR_H
#define _AUTO_PTR_H

namespace test
{    
    template<typename T>
    class auto_ptr
    {
        public:
            //ctor, dtor, copy ctor and assignment
            explicit auto_ptr(T* ptr = 0) throw() 
                : ptr_(ptr) {}

            auto_ptr(auto_ptr& other) throw()
                :ptr_(other.release()) {}

            auto_ptr<T>& operator=(auto_ptr<T>& other)
            {
                reset(other.release());
                return *this;
            }

            template<typename U>
            auto_ptr<T>& operator=(auto_ptr<U>& other) throw()
            {
                reset(other.release());
                return *this;
            }

            template<typename U>
            auto_ptr(auto_ptr<U>& other) throw() 
                : ptr_(other.release()) {}

            //member
            ~auto_ptr() throw() { delete ptr_; }

            T& operator*() const throw() { return *ptr_; }

            T* operator->() const throw() { return ptr_; }

            T* get() const throw() { return ptr_; }         

            T* release() throw()
            { 
                T* temp = ptr_;
                ptr_ = 0;
                return temp;
            }

            void reset(T* ptr = 0) throw()
            {
                if (ptr_ != ptr)
                {
                    delete ptr_;
                    ptr_ = ptr;
                }
            }

        private:
            T* ptr_;
    };
}

#endif

My class is doing pretty much the job then I have read this question and it is clear why auto_ptr_ref is there for. However I would like to have an actual example when the auto_ptr behaves differently without add auto_ptr_ref.

My implementation works correctly with this functions:

template <typename T>
test::auto_ptr<T> source()
{
    return test::auto_ptr<T>(new T());
}

template <typename T>
void sink(test::auto_ptr<T> bye)
{
}

template <typename T>
void useButNotSink(const test::auto_ptr<T> seeYouLater)
{
    std::cout << *seeYouLater << std::endl;
}

With this test program:

test::auto_ptr<double> copyConstructed(source<double>());

std::cout << *copyConstructed << std::endl;
std::cout << copyConstructed.get() << std::endl;

test::auto_ptr<double> assigned(new double(10));
assigned = source<double>();

std::cout << *assigned << std::endl;
std::cout << assigned.get() << std::endl;
*assigned = 2044;

std::cout << *assigned << std::endl;
useButNotSink(assigned);
sink(assigned);
std::cout << assigned.get() << std::endl;

I am sure I am missing something,can you give me an example where the auto_ptr_ref struct and the conversion operators are mandatory to get the correct behaviour?

Thanks


Your very first line

test::auto_ptr<double> copyConstructed(source<double>());

is already non-compilable by any standard-compliant compiler. MSVC will allow it when the C++ language extensions are enabled. Disable the extensions and you will immediately realize the need for auto_ptr_ref.

The mechanics behind auto_ptr_ref was too complicated for MSVC 6.0, so in order to support some resemblance of full std::auto_ptr functionality that compiler had to rely on this compiler extension, i.e. allowing non-const references to be bound to temporary objects. The problem was fixed in later versions of the compiler, but this compiler extension remains enabled by default to this day.


You seem to be using compiler extension. I don't see a copy constructor with const reference argument. As you can't pass a temporary to a non const reference,

test::auto_ptr<double> copyConstructed(source<double>());

should fail to compile (the result of source<double>() being a temporary).

(Note that in C++0X, rvalue reference are a better mean to achieve the effect).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜