关于c++的封装性

关于c++的封装性 

在头文件中定义一个类, 比如说CAlpha。然后用mfc把整个类输出来(在DLL中),供别人调用这个类。

听起来,这个解决方案很不错,模块化,实现部分进行了封装。

但我们实际来看这个例子:

//my_header.h

class CAlpha

{

private:

           int m_nDegree;

public:

          int GetMyDegree( );

          void SetMyDegree( int nNewDegree );

};

当然要加上一些修饰符,才能编译成输出的类。 这里省略。

而当调用者要调用这个类,他(她)需要一个头文件,还需要dll, lib文件。dll、lib文件我就不讨论了。

关键在于调用者使用的头文件。 通常,如果调用者要用 "CAlpha temp_alpha;" 或者"CAlpha* pNewAlpha = new CAlpha( )"的时候,他必须得到这样的头文件。

//my_header.h

class CAlpha

{

private:

           int m_nDegree;

public:

          int GetMyDegree( );

          void SetMyDegree( int nNewDegree  );

};

这好象很平常!

但这恰恰是不平常的地方!

调用者看到了private里面的具体实现的细节!——这极大破坏了封装性。破坏了一个基本的OO原则。

如果调用者用这样一个头文件来new CAlpha行不行呢?

 

class CAlpha

{

public:

          int GetMyDegree( );

          void SetMyDegree( int nNewDegree );

};

不行!因为这个类与原始的实现的类的内存布局不一样,这样new一下,必然导致错误。

我不是OO基本教义派,破坏原则本身并不是非常可怕的。 但除了原则以外,可怕之处在于其他的现实危害。

假设这个类的实现者重新改变了他的实现,比如他删除了m_nDegree,但接口未变,“GetMyDegree()” and "SetMyDegree"都没有改变。 这个时候,他需要向调用者重新发送一个新的头文件吗?

我的答案是:如果调用者可以用new 这个对象的话,他必须重新发送头文件。否则调用者的调用在内存方面几乎必然是出错的。 (调用者必须知道这个类的内存布局,否则他无法new)。

而如果类的实现者在保持接口不变而仅仅是实现方式变化的情况下,还要给调用者提供新的头文件。这个成本就太高了。这个时候,还不如把源代码发送给调用者,让他自己去联编就可以了。

这显然是不经济的。

这个时候,如果想要求不再发送新的头文件给调用者,那就只有一个办法:禁止调用者直接new 这个对象。这个时候,就必须使用类工厂的模式。

在头文件中,增加这样一个函数 CAlpha* CreateNewAlpha( ); 在这个函数中:

这样实现 CAlpha* CreateNewAlpha( )

{

                 return new CAlpha( );

}

CreateNewAlpha输出给调用者,这样就可以了。这个时候,调用者所看到的头文件是:

class CAlpha

{

public:

          int GetMyDegree( );

          void SetMyDegree( int nNewDegree );

};

CAlpha* CreateNewAlpha( );

这样才行。

 

这种看起来古怪的解决方法,都是因为c++的封装性有问题才这样做的。

看来c++要做的事情还是很多的。

这次把上次没写完的东西写了一下。还没有好好修改。先传上去再说。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值