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;
}
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,再重载->呢?完全没有必要啊?是不是有我不知道的什么优点?
谢谢
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;} 完全不一样
class tset
{
public:
int a;
test *operator->(void){return this};
};
上面的代码才是默认的
与这个 //A* operator->() {cout<<"hhh"<<endl;return ptr;} 完全不一样
#6
但是没有一个人能够具体说明重载->的优点是什么哦!!!!!!!!!!!!
#7
使用裸指针 new时一定要记得delete. 很麻烦.
所以想用对象来模拟指针. 要求它可以 * 可以 ->
并且希望在这个对象析构时 . 让它自动 delete p(放到Aptr类的析构函数中);
所以想用对象来模拟指针. 要求它可以 * 可以 ->
并且希望在这个对象析构时 . 让它自动 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;
};
---------------------------
这样的是没有多大的意义,但做成摸板意义就大了。
{
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库中就有许多现成的智能指针类库可以直接使用,在我们自己的程序中,也可以定义自己的智能指针类(类中重载*和-〉运算符),来实现和封装我们特定的操作。
对于一个类,可以在类中重载*和->运算符,此时*和->相当于成员函数
重载->时,函数原型必须是: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;
}
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,再重载->呢?完全没有必要啊?是不是有我不知道的什么优点?
谢谢
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;} 完全不一样
class tset
{
public:
int a;
test *operator->(void){return this};
};
上面的代码才是默认的
与这个 //A* operator->() {cout<<"hhh"<<endl;return ptr;} 完全不一样
#6
但是没有一个人能够具体说明重载->的优点是什么哦!!!!!!!!!!!!
#7
使用裸指针 new时一定要记得delete. 很麻烦.
所以想用对象来模拟指针. 要求它可以 * 可以 ->
并且希望在这个对象析构时 . 让它自动 delete p(放到Aptr类的析构函数中);
所以想用对象来模拟指针. 要求它可以 * 可以 ->
并且希望在这个对象析构时 . 让它自动 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;
};
---------------------------
这样的是没有多大的意义,但做成摸板意义就大了。
{
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库中就有许多现成的智能指针类库可以直接使用,在我们自己的程序中,也可以定义自己的智能指针类(类中重载*和-〉运算符),来实现和封装我们特定的操作。
对于一个类,可以在类中重载*和->运算符,此时*和->相当于成员函数
重载->时,函数原型必须是:Type * operator->();//Type可以是任意类型
重载*时,函数原型必须是:Type operator*();//返回类型没有特殊要求,可以是Type,Type*,Type&
楼主的这个例子,重载*和->看上去意义不大,但是,如果Aptr类中重载的*和->成员函数内部的逻辑相当复杂,我们就可以在在*和->函数内部实现任何复杂的功能,而不仅仅是输出hhh(cout << "hhh" <<endl;).但这些复杂的操作对Aptr类的使用者来说是透明的,使用者不需要关心内部是如何实现的,实际上就是封装了复杂的内部实现。类的使用者仍然把*和->当作普通的指针运算符来使用就可以了。
其实Aptr类可以算作一个智能指针,boost库中就有许多现成的智能指针类库可以直接使用,在我们自己的程序中,也可以定义自己的智能指针类(类中重载*和-〉运算符),来实现和封装我们特定的操作。