C++的“私有”是针对类而言的还是针对类的实例而言的?
问题的起源:
我在看新版的《C++编程思想》的时候,看到拷贝构造函数章节处大致有这么一,非常不解:
Class A {
int n; //私有的n
public:
A(const A& a): n(a.n){} //为什么可以调用a.n,n明明是私有的
}
另外在重载=操作符的时候也有这样的问题。
后来得到的答案是:private是限定异类之间的访问,而不是限定同类不同对象的访问
只有smalltalk是连同类不同对象的访问都限制的
这样就清楚明白的回答了为什么拷贝构造函数可以根据一个对象完整的复制出另一个对象。
但是这样似乎有点不对劲,这样也就是说C++中的一个类是他自己的友员,那样的话
同类的不同对象之间是完全透明的,一个对象可以访问另一个对象所有的成员,包括
私有的。这样是不是很不合理?
比如,(下面的例子少儿不易):
class 男子 {
private:
小鸡鸡 jj;
public:
操作(男子 x);
}
我们定义一个男子的类,男子的特征之一是有个小鸡鸡,这个应当是私有的,
不然后果不堪设想。下面我们假定有两个男子:
男子 a,b;
a.操作(b);
倘若在“操作”的定义中有这么一句:
男子::操作(男子 x){
x.jj = null;
};
这个似乎不太好,即便两个人都是男子,怎么能随便把人家的小鸡鸡喀嚓掉呢,
除非是情敌。。。-_-!
所以我比较赞成smalltalk的做法,把私有限定到对象身上,而不是类上。
那么问题又来了,如果限定到对象上,也就是说传进来的对象,即使是同类对象,
也不能访问它的私有成员,那么拷贝构造函数怎么实现?
我的想法是:
如果那样设计的话,就应该这么理解私有、公有和拷贝构造:
拷贝一个对象的时候,只能基于被拷贝对象公开可见的部分进行新对象的创建。
如果某个私有成员可以通过该对象的某个公开方法取得,则取得并赋值;
若没有方法获得某个私有成员,则应当给它赋一个初始值。
以上缘自在水木上的对问题的讨论。
另外,还有更进一步的YY,假设有个女子的类,假设男子把女子设为friend类,这样
似乎也不太好,那女子可以任意访问男子的所有冬冬。。。所以应该把女子的某个
函数(行为)设为friend,在该行为进行过程中,女子可以访问男子的所有冬冬,
这样似乎才比较合理。。。(太e了,不继续了:p)
我在看新版的《C++编程思想》的时候,看到拷贝构造函数章节处大致有这么一,非常不解:
Class A {
int n; //私有的n
public:
A(const A& a): n(a.n){} //为什么可以调用a.n,n明明是私有的
}
另外在重载=操作符的时候也有这样的问题。
后来得到的答案是:private是限定异类之间的访问,而不是限定同类不同对象的访问
只有smalltalk是连同类不同对象的访问都限制的
这样就清楚明白的回答了为什么拷贝构造函数可以根据一个对象完整的复制出另一个对象。
但是这样似乎有点不对劲,这样也就是说C++中的一个类是他自己的友员,那样的话
同类的不同对象之间是完全透明的,一个对象可以访问另一个对象所有的成员,包括
私有的。这样是不是很不合理?
比如,(下面的例子少儿不易):
class 男子 {
private:
小鸡鸡 jj;
public:
操作(男子 x);
}
我们定义一个男子的类,男子的特征之一是有个小鸡鸡,这个应当是私有的,
不然后果不堪设想。下面我们假定有两个男子:
男子 a,b;
a.操作(b);
倘若在“操作”的定义中有这么一句:
男子::操作(男子 x){
x.jj = null;
};
这个似乎不太好,即便两个人都是男子,怎么能随便把人家的小鸡鸡喀嚓掉呢,
除非是情敌。。。-_-!
所以我比较赞成smalltalk的做法,把私有限定到对象身上,而不是类上。
那么问题又来了,如果限定到对象上,也就是说传进来的对象,即使是同类对象,
也不能访问它的私有成员,那么拷贝构造函数怎么实现?
我的想法是:
如果那样设计的话,就应该这么理解私有、公有和拷贝构造:
拷贝一个对象的时候,只能基于被拷贝对象公开可见的部分进行新对象的创建。
如果某个私有成员可以通过该对象的某个公开方法取得,则取得并赋值;
若没有方法获得某个私有成员,则应当给它赋一个初始值。
以上缘自在水木上的对问题的讨论。
另外,还有更进一步的YY,假设有个女子的类,假设男子把女子设为friend类,这样
似乎也不太好,那女子可以任意访问男子的所有冬冬。。。所以应该把女子的某个
函数(行为)设为friend,在该行为进行过程中,女子可以访问男子的所有冬冬,
这样似乎才比较合理。。。(太e了,不继续了:p)
转载是因为讲的挺好,不过举例嘛,呵呵,有点^^^^^^^