前言
设计一个模仿整型的类来引出下文
class Int
{
private:
int value;
public:
Int(int x = 0) : value(x)
{
cout << "Create Int: " << this << endl;
}
Int(const Int& it) : value(it.value)
{
cout << "Copy Create Int: " << this << endl;
}
Int& operator =(const Int& it)
{
if (this != &it)
{
value = it.value;
}
cout << this << " = " << &it << endl;
return *this;
}
~Int() { cout << "Destroy Int: " << this << endl; }
};
正常指针
在正常申请堆区空间时,我们必须要通过free或 delete释放空间,比较麻烦
int main(void)
{
Int* ip = new Int(10);
delete ip;
return 0;
}
设计的类声明的指针
class Object
{
Int* ip;
public:
Object(Int* s = NULL) : ip(s)
{
cout << "Create Object: " << this << endl;
}
~Object()
{
if (ip != NULL)
{
delete ip;
}
ip = NULL;
cout << "Destroy Object: " << this << endl;
}
};
int main(void)
{
Object obj(new Int(10));
return 0;
}
通过设计这样一个类,可以让他自动释放堆区的空间,不需要再频繁地写delete或free了。
那么问题就是,如果想要取Int类型的值,如何办到?
首先在Int类里写两个取值的方法
int& Value() { return value; }
const int& Value()const { return value; }
然后在 Object 类型中实现指向运算符和解引用运算符的重载:
Int& operator*()
{
return *ip;
}
const Int& operator*() const
{
return *ip;
}
Int* operator->()
{
return &**this;
//return ip;
}
const Int* operator->() const
{
return &**this;
//return ip;
}
这样就可以可以访问Int的值:
int main(void)
{
Object obj(new Int(10));
(*obj).Value();
obj->Value();
return 0;
}
解释:
*ip :ip存放 Int的地址,那 *ip就是 Int本身,所以对Object类型解引用就是 Int本身,可以通过(.)运算符来访问Int的成员。
&**this: this表示 Object的对象,*this为 对象本身,**this表示调用 该对象的 operator *(),该运算符返回 *ip, 再取地址(&),即 ip本身的地址。
总之,我们使用一个对象管理指针,和拿一个裸指针管理一个指针,是有一定的好处的,实现内存的自动化管理。