重载解引操作和箭头操作
首先我们的类成员中并没有指针,我们本打算定义一个新的类,这个类中的数据成员就是指向Student类对象的指针。但是根据前面提过的“智能指针”以及引用计数原理,我们的程序变成了这样:
//智能指针
class StdPtr
{
friend class StudentPtr;
//实际的指针
Student *sp;
//引用计数
size_t use;
//构造函数
StdPtr(Student *p):sp(p),use(1){cout<<"StdPtr构造"<<endl;}
//析构函数
~StdPtr(){cout<<"StdPtr析构"<<endl;delete sp;}
};
class StudentPtr
{
public:
//复制操作符
StudentPtr(const StudentPtr& orig):ptr(orig.ptr){++ptr->use;}
//赋值操作符
StudentPtr& operator=(const StudentPtr&);
//构造函数
StudentPtr(Student *p):ptr(new StdPtr(p)){cout<<"StudentPtr构造"<<endl;}
//析构函数
~StudentPtr()
{
cout<<"StudentPtr析构"<<endl;
if(--ptr->use == 0)
delete ptr;
}
//重载解引操作符:
Student &operator*(){return *ptr->sp;}
//重载箭头操作符:
Student *operator->(){return ptr->sp;}
//与之对应的const版本
const Student &operator*()const{return *ptr->sp;}
const Student *operator->()const{return ptr->sp;}
private:
StdPtr *ptr;
};
我们在StudentPtr中重载了解引和箭头操作。因为StudentPtr本意为指向Student的指针,所以对它解引应该返回一个Student对象的引用,对它的箭头操作应该返回Student的成员。想清楚了这个道理,重载程序实际上就简单了。还有一点要注意,解引操作是一元操作,这里定义为成员函数,所以没有形参;而箭头操作看起来像是二元操作符:接受一个对象和一个成员名,而实际上,箭头操作的右操作数并不是一个表达式,而是类成员的标示符,编译器自动帮你处理了将一个标示符传递给函数以获取类成员的工作。
通常,对于指针和箭头都应该定义两个版本,一个是const,另一个是非const,const版本返回const引用以防止用户改变基础对象,这与STL标准库的思想很像,既有普通迭代器,也有const迭代器。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。