一、类的设计的几个问题
1、数据成员变量私有化:
大多数public变量都是不安全的,我们无法保证使用者对它进行无意的篡改,对于一些成员变量,如果类外需要对其进行访问,可以通过两种方式对数据进行保护,一种是函数的调用,一种是引用的实现;如下代码所示:
class A
{
public:
int length;
......
}
函数的方式实现对数据的保护:(注:类成员函数后面加const修饰,表明成员函数隐式传入的指针是const指针,因此不能对类数据成员进行修改;)
class A
{
public:
int Getlength()const;
private:
int length;
......
}
引用的实现:
2、对于数据成员要在构造函数里面进行初始化,在析构函数里面进行资源的释放
3、对于抽象类析构函数要声明为虚函数,保证对象的正确释放;而对于普通类来说,不要定义虚析构函数,会增加虚函数表的内存开销;
4、赋值构造函数的问题:简单来说,如果在你的类里有分配内存的指针数据,就需要赋值构造函数,如果没有,就不需要,因为这涉及到一个深拷贝和浅拷贝的问题,在函数析构的时候会导致释放报错。如果没有显示定义一个赋值构造函数,系统会默认一个public的赋值构造函数,如果我们想禁掉这个公共接口,我们可以显示的申明为private;
5、对于成员函为保证数据的安全,要加const修饰;
二、代理类
代理类的作用就是将类型不同的但是具有相关联的对象以容器的形式进行管理。
1:问题的提出
class A
class B:public A
class C:public B
考虑下面的实现
{
A a[100];
B b;
A[i++] = b;
}
有两个问题:第一个就是作为基类A,如果类里面有纯虚函数的话,这种申明是不合法的,因为含有纯虚函数的类是不能够实例化的,第二个问题就是赋值,仅仅将B类里面和A类里面共有的数据进行了赋值,对于B有A无的数据,赋值操作将会丢失这部分信息。
2:解决方法一
采用指针的方法来解决
{
A *a[100];
B b;
A[i++] = &b;
}
采用这样一种方法虽然能够解决上述两类问题,但是又会产生一个新问题,因为对于B对象,如果是局部变量,随着它的生命周期的结束,对象销毁后,指针的指向就无法确定了
3:解决方法二:
采用指针加副本的形式
{
A *a[100];
B b;
A[i++] = new B(b);
}
采用这样一种方法解决了上述问题,但是同样又会产生新的问题:
当我们需要用a[i]指向一个新建的对象B,而这个对象正好是a[j],
如果我们采用如下形式:a[i] = a[j]的话。就会出现解决方法一所产生的问题;
如果采用a[i] = new A(a[j]);就会产生一开始部分复制的问题;
4、代理类的解决
首先定义虚复制函数;如下:
class A
{
......
virtual A* Copy() const= 0;
}
class B:public A
{
......
virtual A* Copy() { return B(*this);}
}
class C:public B
{
......
virtual A* Copy() { return C(*this);}
}
然后定义个代理类
class D
{
......
D& operator=(A* a);
private:
A* m_A;
}
D& D::operator=(A* a)
{
m_A = a.Copy();
}
这样就可以解决问题了:如下:
D d[100];
B b;
d[i] = b;
三、句柄类
需要解决的问题:简单的来说就是需要共享同一个对象,因为如果有多个指向同一个对象的指针存在时,如果对象很大或是不能被复制的资源时,通过复制副本的方式就行不通了,而如果采用指针的方式进行时也会产生两个问题,一个是暴露了内存分配的细节,第二一个就是无法判断何时释放资源。
第一种句柄类模式:将整个结构模块化为三个模块,分别为句柄类、实际类、引用技术类。这样一种模式是将引用计数交由引用计数类来进行管理,
第二种句柄模式:是将引用计数交由句柄类来进行管理。
我所理解的句柄类作用:如果采用指针获取的方式对对象进行多处指向,那么我们就无法有效的释放对象,因为当我们释放对象的时候,无法保证其他指向该对象的指针不再对该对象进行操作,另一个就是我们无法正确实现写操作,如果通过副本的方式的话又增大了内存的开销。而通过句柄类的方式,对于对象我们实际上只分配了一块内存,然后每多一个指向改对象时,只多了一个句柄对象,这个对象相比与大的实际对象来说小的多。然后释放该指向时,只需要释放句柄对象,只有当实际对象无引用时,才将实际对象销毁,而对于对象,如果有写操作,才复制实际对象。
注:需要电子档《C++沉思录》的同学可以留下邮箱。
浙公网安备 33010602011771号