2011年4月16日星期六

拷贝函数使用其他类的protected/privte成员

从写C++开始,我就没搞明白过为什么拷贝构造函数里可以直接使用其他类的protected/privte成员,今天终于得到了答案

发信人: ilovecpp (cpp), 信区: CPlusPlus
标 题: Re: 为什么子类不能访问父类的protected变量?
发信站: 水木社区 (Fri Mar 25 10:07:25 2011), 站内

【 在 RoachCock (我的饭盒我的饭) 的大作中提到: 】
: 这个限制很无聊,和可访问同类型其他对象私有成员的设计矛盾。C++
: 的访问控制应该全是类级别而不是对象级别的。

你看见的这个不协调感其实不是一个孤立事件,而是由于C++试图把
Abstract Data Type (ADT)和object两种概念(甚至还包括C
struct)统一在class这一个框架下,由此带来的诸多矛盾和复杂
性之一。

关于ADT v.s. object,参见:
On Understanding Data Abstraction, Revisited.
William R. Cook. University of Texas at Austin
http://citeseerx.ist.psu.edu/viewdoc/download?
doi=10.1.1.150.3462&rep=rep1&type=pdf

简言之,对于ADT和object,对象的内部结构都对用户隐藏。但是
ADT要求程序里一个类型的所有对象有相同的内部结构,从而不必对
定义在此类型上的操作隐藏。映射到C++,这就是"private是class
scoped"。学过其他OOPL的人对此常有疑问,答案是这个设计并非
源自OOP,而是源自ADT。D&E上讲C++的原型没有virtual function,
那么很可能Stroustrup最早引入class时,他的理解更接近ADT而
不是object。

而对于object,对象的内部结构在对象之外都不可见,包括同类的
对象。Protected只是让对象A的蓝图(父类)可以被对象B的蓝图
(子类)复用,而不能打破OOP的核心教条:"对象的内部结构对外
隐藏"。

所以private和protected的不协调是因为它们来自不同的数据抽象。
这一冲突在class里一再重演:
* 成员函数缺省应该non-virtual还是virtual
* 变量/数据成员应该是value还是reference语义