C++ Tutorial/Pointer/auto ptr — различия между версиями
Admin (обсуждение | вклад) м (1 версия: Импорт контента...) |
|
(нет различий)
|
Версия 14:21, 25 мая 2010
Содержание
class auto_ptr: improved standard conforming implementation
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
/* class auto_ptr
* - improved standard conforming implementation
*/
namespace std {
// auxiliary type to enable copies and assignments (now global)
template<class Y>
struct auto_ptr_ref {
Y* yp;
auto_ptr_ref (Y* rhs)
: yp(rhs) {
}
};
template<class T>
class auto_ptr {
private:
T* ap; // refers to the actual owned object (if any)
public:
typedef T element_type;
// constructor
explicit auto_ptr (T* ptr = 0) throw()
: ap(ptr) {
}
// copy constructors (with implicit conversion)
// - note: nonconstant parameter
auto_ptr (auto_ptr& rhs) throw()
: ap(rhs.release()) {
}
template<class Y>
auto_ptr (auto_ptr<Y>& rhs) throw()
: ap(rhs.release()) {
}
// assignments (with implicit conversion)
// - note: nonconstant parameter
auto_ptr& operator= (auto_ptr& rhs) throw() {
reset(rhs.release());
return *this;
}
template<class Y>
auto_ptr& operator= (auto_ptr<Y>& rhs) throw() {
reset(rhs.release());
return *this;
}
// destructor
~auto_ptr() throw() {
delete ap;
}
// value access
T* get() const throw() {
return ap;
}
T& operator*() const throw() {
return *ap;
}
T* operator->() const throw() {
return ap;
}
// release ownership
T* release() throw() {
T* tmp(ap);
ap = 0;
return tmp;
}
// reset value
void reset (T* ptr=0) throw() {
if (ap != ptr) {
delete ap;
ap = ptr;
}
}
/* special conversions with auxiliary type to enable copies and assignments
*/
auto_ptr(auto_ptr_ref<T> rhs) throw()
: ap(rhs.yp) {
}
auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { // new
reset(rhs.yp);
return *this;
}
template<class Y>
operator auto_ptr_ref<Y>() throw() {
return auto_ptr_ref<Y>(release());
}
template<class Y>
operator auto_ptr<Y>() throw() {
return auto_ptr<Y>(release());
}
};
}
const auto_ptr
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iostream>
#include <memory>
using namespace std;
/* define output operator for auto_ptr
* - print object value or NULL
*/
template <class T>
ostream& operator<< (ostream& strm, const auto_ptr<T>& p)
{
// does p own an object ?
if (p.get() == NULL) {
strm << "NULL"; // NO: print NULL
}
else {
strm << *p; // YES: print the object
}
return strm;
}
int main()
{
const auto_ptr<int> p(new int(42));
const auto_ptr<int> q(new int(0));
const auto_ptr<int> r;
cout << "after initialization:" << endl;
cout << " p: " << p << endl;
cout << " q: " << q << endl;
cout << " r: " << r << endl;
*q = *p;
// *r = *p; // ERROR: undefined behavior
*p = -77;
cout << "after assigning values:" << endl;
cout << " p: " << p << endl;
cout << " q: " << q << endl;
cout << " r: " << r << endl;
// q = p; // ERROR at compile time
// r = p; // ERROR at compile time
}
after initialization: p: 42 q: 0 r: NULL after assigning values: p: -77 q: 42 r: NULL
Define output operator for auto_ptr print object value or NULL
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iostream>
#include <memory>
using namespace std;
/* define output operator for auto_ptr
* - print object value or NULL
*/
template <class T>
ostream& operator<< (ostream& strm, const auto_ptr<T>& p)
{
// does p own an object ?
if (p.get() == NULL) {
strm << "NULL"; // NO: print NULL
}
else {
strm << *p; // YES: print the object
}
return strm;
}
int main()
{
auto_ptr<int> p(new int(42));
auto_ptr<int> q;
cout << "after initialization:" << endl;
cout << " p: " << p << endl;
cout << " q: " << q << endl;
q = p;
cout << "after assigning auto pointers:" << endl;
cout << " p: " << p << endl;
cout << " q: " << q << endl;
*q += 13; // change value of the object q owns
p = q;
cout << "after change and reassignment:" << endl;
cout << " p: " << p << endl;
cout << " q: " << q << endl;
}
after initialization: p: 42 q: NULL after assigning auto pointers: p: NULL q: 42 after change and reassignment: p: 55 q: NULL
Demonstrate an auto_ptr
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "constructing\n";
}
~MyClass() {
cout << "destructing\n";
}
void f() {
cout << "f()\n";
}
};
int main()
{
auto_ptr<MyClass> p1(new MyClass), p2;
p2 = p1; // transfer ownership
p2->f();
// can assign to a normal pointer
MyClass *ptr = p2.get();
ptr->f();
return 0;
}
constructing f() f() destructing