句柄
从代理类我们继续考虑,怎样可以避免对象复制呢,引出句柄
Class Point{
public:
Point():xval(0),yval(0){}
Point(int x,int y):xval(x),yval(y){}
int x() const{return xval;}
int y() const{return yval;}
Point& x(int xv){xval = xv;return *this;}
Point& y(int yv){yval = yv;return *this;}
private:
int xval,yval;
}
句柄是什么?我们希望
Point p;
Handle h(p);
是将h绑定到p上,但这里有管理和控制的问题,什么时候删除p呢
Class Handle{
public:
Handle();
Handle(int,int);
Handle(const Point&);
Handle(const Handle&);
Handle& operate=(const Handle&);
~Handle();
int x() const;
Handle& x(int);
int y() const;
Handle& y(int);
}
允许多个句柄绑定到同一个对象上,则需要计数,但这个计数的属性不能是Handle类的,
因为如果这样,那减少一个应用要去修改其他句柄的计数。也不能是Point类的,因为这样就改了原来的代码了。
这样我们设计加入一个类负责为每个Point对象计数
Class UPoint{
private:
friend class Handle;
Point p;
int u;
Upoint():u(1){}
Upoint(int x,int y):p(x,y),u(1){}
Upoint(const Point& p0):p(p0),u(1){}
}
那么Handle类改成什么样呢:
Class Handle{
public:
Handle();
Handle(int,int);
Handle(const Point&);
Handle(const Handle& h):up(h.up){
++up->u;
}
Handle& operate=(const Handle& h){
++h.up->u;
if(--up->u==0)
delete up;
up = h->up;
return *this;
}
~Handle(){
if(--up->u == 0)
delete up;
}
int x() const {return up->p.x();}
Handle& x(int x0){
up->p.x(x0);
return *this;
}
int y() const {return up->p.y();}
Handle& y(int y0){
up->p.y(y0);
return *this;
}
private:
//后来新加的
Upoint * up;
}
这种是指针语义,永远不必复制UPoint对象,如果是需要值语义,则需要复制UPoint对象,保证UPoint不能同时被两个以上Handle所引用。
这可以通过看计数是否为1来判断。同时另外一种技术叫"Copy on write"写时复制。意思是对于不影响对象值的方法不去另外复制对象,
只有在会影响对象值的方法中去另外复制一个相同的对象:
Handle& Handle::x(int x0){
if(up->u != 1){//如果有两个句柄指向同一个对象,则这里的计数已经大于1了,只是因为不去修改对象的值,一直没有复制出另外一个对象。
--up->u;
up = new UPoint(up->p);
}
up->p.x(x0);
return *this;
}
这样的设计句柄有个缺点,就是需要定义一个具有类型为Point的成员的新类,这使得事情比较复杂,尤其是当要把Handle捆绑到Point的子类的时候。
怎样改进?这里有个方法,但并没有经常在使用的
class Handle{
public:
//no change
private:
Point* p; //去掉了UPoint
int* u;
}
//新构造出来的Handle,初始计数=1就可以了
Handle::Handle():u(new int(1),p(new Point())){}
Handle::Handle(int x,int y):u(new int(1),p(new Point(x,y))){}
Handle::Handle(const Point& p0):u(new int(1),p(new Point(p0))){}
//复制构造函数,指针,计数的int地址都相同,计数加1
Handle::Handle(Handle& h):u(h.u),p(h.p){++*u;}
//赋值操作,就是原来this的计数要减1,新的指针计数加1.
Handle& Handle::operate=(const Hanlde& h){
++*h.u;
if(--*u ==0){
delete u;
delete p;
}
u = h.u;
p = h.p;
return &this;
}
Handle::~Handle(){
if(--*u ==0 ){
delete u;
delete p;
}
}
再引申就是把int* u这个u定义出一个专门的类来。略。
分享到:
相关推荐
第 1 节 句柄类的结构让我们开始讲句柄 (handle) 的第一篇文章,假如你想要在Open CASCADE 上开发软件的话,这篇文章虽然比较简单但是非常重要
主要介绍了C++ 中CloseHandle 函数--关闭一个句柄的相关资料,需要的朋友可以参考下
演示了继承中的易错点,演示了两种常用C++句柄类的封装方式,前者适用于类的基类指针管理以便实现多态,后者不仅管理基类指针还管理子类对象的创建。
火山PC,dm进阶操作-获取模块-句柄-互斥体可以用来提权,降权,句柄操作,关闭互斥体操作 互斥体一般用来关闭多开限制使用。 包括C++版的dm源码,都在里面。
linux 学习--句柄学习,关于linux句柄的学习笔记。
本文件包含了实现句柄类的源文件,通常我们不能将基类和派生类对象同时存储在一个容器中,比如vector或者multiset,代码中通过利用句柄类解决了这个问题。详细解释可以参考博文...
C++指针及句柄,深入理解 指针的奥秘 .
用C++实现的句柄类,有利于初学者理解什么是句柄~~
目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 1.1.1 对象:特性+行为 1 1.1.2 继承:类型关系 1 1.1.3 多态性 2 1.1.4 操作概念:OOP程序像什么 3 1.2 为什么C++会成功 3 1.2.1 较好的C 3 1.2.2 采用渐进...
C++基础辅助类库,比如异步进行-Thread,安全句柄-CHandle,资源守卫-Guard,XML解析-rapidxml,以及其他注册表、文件基础操作
C++中句柄和指针的区别,从广义上,能够从一个数值拎起一大堆数据的东西都可以叫做句柄。句柄的英文是"Handle",本义就是"柄",只是在计算机科学中,被特别地翻译成"句柄",其实还是个"柄"。从一个小东西拎起一大堆...
资源介绍:通过句柄操作创建,发送文本消息,发送消息,禁止,可视,取标题, 取窗口风格,取窗口扩展风格,取当前句柄,取父句柄,取类名,取内容,取上一个句柄,取下一个句柄,取子句柄,通过标题创建,通标题...
1、普通函数调用 2、dll内子线程回调函数 3、借助OpenCV将dll图片显示到c#句柄(暂未实现 参照https://blog.csdn.net/u012250337/article/details/51601905)
c++ vc6 句柄类
句柄类存储和管理基类指针。指针所指的对象的类型可以变化,即可以指向基类对戏那个又可以指向派生类类型对象。用户通过句柄类访问继承层次的操纵。因为句柄类使用指针执行操作,虚成员的行为将在运行时根据句柄实际...
类似SPY++查看窗口句柄,CLASS,并可以修改窗口名称的源码。
简单介绍窗口句柄的文章
Java调用Win32获取窗口句柄JNative-1.3.2 Java调用Win32获取窗口句柄JNative-1.3.2
这是一份源代码,当前使用的VS2017+opencv3,代码有后台句柄截图+通过句柄发送按键事件,鼠标事件的功能。
2011年竹海清风编程组首次发行的竹海清风-句柄捕获专家。可捕获所有程序句柄(包括其控件),大家快来体验吧!编程必备~ 本程序是免安装版,解压后即可使用!