首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

百思不得其解,protected到底有什么存在的必要?解决思路

2013-03-16 
百思不得其解,protected到底有什么存在的必要?原谅我重提protected这个被讨论烂了的关键字,只是我是在想不

百思不得其解,protected到底有什么存在的必要?
原谅我重提protected这个被讨论烂了的关键字,只是我是在想不出来什么场景下必须protected不可,刚才看了一下《C++语言的设计与演化》中关于保护成员的论述,仍然没看出个所以然。
[解决办法]
好吧,我简单举例,模拟Qt中常见的模式:委托模式的写法


class ToolPrivate  // 正如,下面所示,外界无法构造该对象。只能被继承类在堆上构建。
{
protected:
  ToolPrivate( void );
  ~ToolPrivate( void );
  

  ......

private: 
   // 屏蔽堆上构建、拷贝构建,赋值操作
   ToolPrivate * operator new( void ) = 0;
   ToolPrivate operator = ( void ) = 0;
   ToolPrivate( ToolPrivate & ) = 0;
   


   .....
}


class Tool : public ToolPrivate
{
   ToolPrivate toolPrivate; // 我可以在栈上创建自己的方法类

}


[解决办法]
如果有这样一种需求,需要继承类访问基类成员,但是又不想让引用该类(没有继承)的其他类访问该类的成员,应该怎么做啦?如果如果放松private为public,那是不是引用该类的其它类就可以直接访问该类成员,暴露了内部细节,如果不放开private,那继承类是不是也不能直接访问了?protected,不尽C++使用了,java同样也保留了这个关键字,他们的意思基本相同,而且java还多了friendly。在接口设计时,protected很有用。
[解决办法]
类似这类问题,不必深究。只要知道某个特征能做什么事情就可以了,用不着去费劲琢磨要如何使用这些特征。

你看不出有什么用,说明在你的应用场合不需要,这类特征不是为你设计的。既然用不到,也就无需了解这么清楚。当你的应用中真的感到需要这样的特征时,自然就会理解其用途。
[解决办法]
1, protected成员可以在子类中访问,可以避免不必要get/set或using
2,protected 继承 
[解决办法]
善用protected可以强化封装性
一个简单的例子


class Player
{
  public:
    //some functions and virtual functions
    
  protected :
    virtual Skill const& get_money();
    virtual Skill const& get_skill();
    
    virtual Money const& set_money(int, int);
    virtual Money const& set_skill(std::string const&, int);    
};

//Haken : 角色名
class Haken : public Player
{
    //...
};


如此一来,其他class就不能access Player的protected member function
只有属于同一个class体系的才能够access(也就是说除非你是player才能access)

以下是我个人的理解,抛砖引玉

何为封装?所谓封装,就是把users不需要知道的细节藏起来
一个简单的function, qsort, printf就是一种封装的技术
他们把内部的实作隐藏起来,我们使用的时候只需要知道这些
Api的preconditions和postcondition就行了,不需要知道
他门内部的实作细节,这就是封装

那么有了function,为何还需要class?class带来了什么好处?
class最大的好处就是他可以保留状态,把动作(function)和变数
绑在一起,加强资料的区域性(member data只有class可见)
public, protected, private这三个关键字则进一步的强化了
封装的能力(oop中最重要也最珍贵的能力)
凡是我们不想被users知道的部分,我们都可以用关键字private或
protected封装起来(一般都是private啦,protected用的很少)

我再举个例子

struct IamOpen
{  
  //don't access these data
  int num_; 
  int money_;
};

class IamClose
{
  private :
    int num_;
    int money_;
};

你觉得那个比较方便?你会选择透过编译器直接约束users的行为


还是透过文件警告users?
文件和注解很重要,但是都远不如代码重要

最后一点,继承少用
对待继承只有两种态度
第一 : 不要用他
第二 : 谨慎的使用他

code complete和exceptional c++对此都有着墨
exceptional c++对继承的利弊和使用时机分析的相当好
[解决办法]
啊,我的player忘了加上virtual destructor
其实现在有很多技术可以使用
随着std::bind,std::function和lambda的出现
以及越来越强大的template
在c++中,继承的地位已经不如当年那么重要了
[解决办法]
既然LZ已经知道三者的区别,这个问题就没有什么好讨论的了,
语言标准就是这么定的,你可以有很多种实现这种机制或者语法表述的方式,
但C++选择了此种方式,清晰而明了,兼顾了多种情况,似乎不存在不方便的地方,
你可以只用public,但语言标准修改是个大事情。



[解决办法]

引用:
原谅我重提protected这个被讨论烂了的关键字,只是我是在想不出来什么场景下必须protected不可,刚才看了一下《C++语言的设计与演化》中关于保护成员的论述,仍然没看出个所以然。


考虑这样一个场景,你开发一个基础库,这个基础库的用户分为两种,一种是使用者,对于这种用户来说,你无须通过protected来向他们隐藏什么,private就很好了;另一种是库开发者,基于你的基础库扩展功能,你不应该考虑为他们提供点什么吗?

热点排行