有必要重载->吗????

时间:2022-05-18 17:07:25
各位大侠:通常定义一个类之后,我可以这样使用该类的指针:
class A
{
    public:
A(int i=0):a(i) {}
void display() {  cout<<a<<endl;}
    private:
int a;
};

int main(int argc, char* argv[])
{
    A a,*p;
p=&a;
p->display();
return 0;
}

但是,我也可以在定义一个类APtr,它是A的指针类,那么:
#include <iostream.h>

class A
{
    public:
A(int i):a(i) {}
void display() {  cout<<a<<endl;}
    private:
int a;
};

class Aptr
{
    public:
Aptr(A& aa):ptr(&aa) {}
A& operator*() {cout<<"hhh"<<endl;return *ptr;}
A* operator->() {cout<<"hhh"<<endl;return ptr;}
private:
A *ptr;
};

void main()
{
    A m(4);
Aptr p(m);
p->display();
(*p).display();
}


我的问题是:既然我可以直接用C++预定义的指针A* p,何必在定义一个类APtr,并且重载->呢???这不是很麻烦吗?或许有别的我不知道的好处?智能指针又是什么?和我问的这个东东有关吗??请各位大侠一定讲明重载->的好处,谢谢!!!

11 个解决方案

#1


如果是Aptr p(m);的话,不重载->的话,你无法调用预定义的->操作符,因为它不是一个指针
Aptr *p = new Aptr(p);
这里的话,如果不重载.p->//这里必须指向Aptr的类成员的操作,也就是说你的Aptr类必须有一个display的成员函数

class Aptr
{
    public:
Aptr(A& aa):ptr(&aa) {}
//A& operator*() {cout<<"hhh"<<endl;return *ptr;}
//A* operator->() {cout<<"hhh"<<endl;return ptr;}
void display(){cout<<"hhh"<<endl;ptr->display();}
private:
A *ptr;
};

void main()
{
    A m(4);
//Aptr p(m);
Aptr *p = new Aptr(m);
p->display();
(*p).display();
delete p;
}

#2


谢谢,但是我是问的明明我可以通过
    A a,*p;
    p=&a;
    p->display();来使用A类型的指针,
为什么可以再定义一个指向A类型的指针类APtr,再重载->呢?完全没有必要啊?是不是有我不知道的什么优点?
谢谢

#3


作者是想设计一个类似auto_ptr的东西吧。。

#4


否则就没法用类来封装指针了

#5


楼主不懂->的操作符号吧,->的默认处理是这样的
class tset
{
public:
  int a;
  test *operator->(void){return this};
};
上面的代码才是默认的
与这个 //A* operator->() {cout<<"hhh"<<endl;return ptr;} 完全不一样

#6


但是没有一个人能够具体说明重载->的优点是什么哦!!!!!!!!!!!!

#7


使用裸指针 new时一定要记得delete. 很麻烦. 
所以想用对象来模拟指针. 要求它可以 * 可以 -> 
并且希望在这个对象析构时 . 让它自动 delete p(放到Aptr类的析构函数中); 
 

#8


楼主看看<<c++设计新思维>>  7.Smart Pointers(智能指针)

#9


template 编程这种东西很多的,经常使用,多多练习会减少开发时间,你会发现他有好多方向的好处

#10


class Aptr
{
    public:
Aptr(A& aa):ptr(&aa) {}
A& operator*() {cout<<"hhh"<<endl;return *ptr;}
A* operator->() {cout<<"hhh"<<endl;return ptr;}
private:
A *ptr;
};
---------------------------
这样的是没有多大的意义,但做成摸板意义就大了。

#11


对于一个指针,可以使用运算符*和运算符->,-〉相当于(*).如:p->相当于(*p).

对于一个类,可以在类中重载*和->运算符,此时*和->相当于成员函数

重载->时,函数原型必须是:Type * operator->();//Type可以是任意类型
重载*时,函数原型必须是:Type operator*();//返回类型没有特殊要求,可以是Type,Type*,Type&

楼主的这个例子,重载*和->看上去意义不大,但是,如果Aptr类中重载的*和->成员函数内部的逻辑相当复杂,我们就可以在在*和->函数内部实现任何复杂的功能,而不仅仅是输出hhh(cout << "hhh" <<endl;).但这些复杂的操作对Aptr类的使用者来说是透明的,使用者不需要关心内部是如何实现的,实际上就是封装了复杂的内部实现。类的使用者仍然把*和->当作普通的指针运算符来使用就可以了。

其实Aptr类可以算作一个智能指针,boost库中就有许多现成的智能指针类库可以直接使用,在我们自己的程序中,也可以定义自己的智能指针类(类中重载*和-〉运算符),来实现和封装我们特定的操作。

#1


如果是Aptr p(m);的话,不重载->的话,你无法调用预定义的->操作符,因为它不是一个指针
Aptr *p = new Aptr(p);
这里的话,如果不重载.p->//这里必须指向Aptr的类成员的操作,也就是说你的Aptr类必须有一个display的成员函数

class Aptr
{
    public:
Aptr(A& aa):ptr(&aa) {}
//A& operator*() {cout<<"hhh"<<endl;return *ptr;}
//A* operator->() {cout<<"hhh"<<endl;return ptr;}
void display(){cout<<"hhh"<<endl;ptr->display();}
private:
A *ptr;
};

void main()
{
    A m(4);
//Aptr p(m);
Aptr *p = new Aptr(m);
p->display();
(*p).display();
delete p;
}

#2


谢谢,但是我是问的明明我可以通过
    A a,*p;
    p=&a;
    p->display();来使用A类型的指针,
为什么可以再定义一个指向A类型的指针类APtr,再重载->呢?完全没有必要啊?是不是有我不知道的什么优点?
谢谢

#3


作者是想设计一个类似auto_ptr的东西吧。。

#4


否则就没法用类来封装指针了

#5


楼主不懂->的操作符号吧,->的默认处理是这样的
class tset
{
public:
  int a;
  test *operator->(void){return this};
};
上面的代码才是默认的
与这个 //A* operator->() {cout<<"hhh"<<endl;return ptr;} 完全不一样

#6


但是没有一个人能够具体说明重载->的优点是什么哦!!!!!!!!!!!!

#7


使用裸指针 new时一定要记得delete. 很麻烦. 
所以想用对象来模拟指针. 要求它可以 * 可以 -> 
并且希望在这个对象析构时 . 让它自动 delete p(放到Aptr类的析构函数中); 
 

#8


楼主看看<<c++设计新思维>>  7.Smart Pointers(智能指针)

#9


template 编程这种东西很多的,经常使用,多多练习会减少开发时间,你会发现他有好多方向的好处

#10


class Aptr
{
    public:
Aptr(A& aa):ptr(&aa) {}
A& operator*() {cout<<"hhh"<<endl;return *ptr;}
A* operator->() {cout<<"hhh"<<endl;return ptr;}
private:
A *ptr;
};
---------------------------
这样的是没有多大的意义,但做成摸板意义就大了。

#11


对于一个指针,可以使用运算符*和运算符->,-〉相当于(*).如:p->相当于(*p).

对于一个类,可以在类中重载*和->运算符,此时*和->相当于成员函数

重载->时,函数原型必须是:Type * operator->();//Type可以是任意类型
重载*时,函数原型必须是:Type operator*();//返回类型没有特殊要求,可以是Type,Type*,Type&

楼主的这个例子,重载*和->看上去意义不大,但是,如果Aptr类中重载的*和->成员函数内部的逻辑相当复杂,我们就可以在在*和->函数内部实现任何复杂的功能,而不仅仅是输出hhh(cout << "hhh" <<endl;).但这些复杂的操作对Aptr类的使用者来说是透明的,使用者不需要关心内部是如何实现的,实际上就是封装了复杂的内部实现。类的使用者仍然把*和->当作普通的指针运算符来使用就可以了。

其实Aptr类可以算作一个智能指针,boost库中就有许多现成的智能指针类库可以直接使用,在我们自己的程序中,也可以定义自己的智能指针类(类中重载*和-〉运算符),来实现和封装我们特定的操作。