I try to understand the following code (taken from here ):
template <class T> class auto_ptr
{
T* ptr;
public:
explicit auto_ptr(T* p = 0) : ptr(p) {}
~auto_ptr() {delete ptr;}
T& operator*() {return *ptr;} // <----- The problematic row.
T* operator->() {return ptr;}
// ...
};
I cannot understand what do we mean when we use T&
as a return type of a function. If T
is a pointer to an integer (or any other type), then I would interpret T&
as integer (or any other corresponding type). But in the above given code T
is not a pointer. T
is a class, and one of its members ( ptr
) is a pointer to objects of this class but T
is not a class of pointers. So, what does T&
as a return type mean?
It means the same as outside the context of a function's return type, ie T&
is a reference to T
. In this case, the function returns a reference to an object of type T
that the caller can use to observe (and also alter, if T
is not const
-qualified) the referenced object.
T&
is simply a reference to type T
. the function returns a reference to an object of class T
.
T is a class, and one of its members (ptr) is a pointer to objects of this class but T is not a class of pointers.
ptr
is not a member of class T
. It is a member of class auto_ptr<T>
. ptr
is a pointer to T
. But the fact that T
is not a "class of pointers" (whatever that means) does not prevent something being a pointer to a T
.
std::string
is a class - of strings, not pointers.
std::string str;
is an object of class std::string
.
&str
is the address of str
std::string * ps = &str;
is a pointer to an std::string
.
From the top:
template <class T> class auto_ptr
is a class template whose sole template parameter is class T
. You instantiate the template by specifying some actual class for T
and declaring some object of the resulting type:
auto_ptr<std::string> aps;
That gives you another actual class, "auto-pointer-to-string", which is exactly like:
class auto_ptr_to_string
{
std::string * ptr;
public:
explicit auto_ptr(std::string * p = 0) : ptr(p) {}
~auto_ptr() {delete ptr;}
std::string & operator*() {return *ptr;}
std::string * operator->() {return ptr;}
// ...
};
And aps
is an object defined like that.
The class has a data member ptr
, which is a pointer to an std::string
.
The class also has an operator:
std::string & operator*() {return *ptr;}
This operator defines the behaviour that results from applying the '*'-prefix to an object of type auto_ptr<std::string>
, eg *aps
.
The definition of the operator tells you that it returns a reference to an std::string
, and that the std::string
referred to by this reference is *ptr
, which means "the one referred to by the data member ptr
".
So:
auto_ptr<std::string> aps(new std::string("Get it?"));
constructs an auto_ptr<std::string>
called aps
and the constuctor initializes the data member aps.ptr
with a pointer to a dynamically allocated std::string
containing "Get it?".
And:
std::string s = *aps;
according to the definition of auto_ptr<std::string>::operator*()
, declares an std::string
s
and initializes it with the std::string
referred to by aps.ptr
, namely that one containing "Get it?"
Finally the class T
syntax for template parameters does not actually restrict their values to classes: auto_ptr<int>
, for example, is fine, though int
is not a class type. And I reiterate Mike Seymour's comment about auto_ptr
being a bad old thing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.