我指的是“用c ++思考”一书中提到的一个练习。 下面的代码片段为调用h.play抛出了一个错误,我明白了,因为 我是私人会员。但我期待电话me.play的同样错误。如果我评论呼叫h.play代码编译好。为什么调用me.play没有错误?
class Buddy {};
template<class T> class My {
int i;
public:
void play(My<Buddy>& s) {
s.i = 3;
}
};
int main() {
My<int> h;
My<Buddy> me, bud;
h.play(bud);
me.play(bud);
}
三江源。
[编辑]有没有办法看看编译器为
生成了什么代码My<int> h and
My<Buddy> me
? (类似于-E编译器标志的任何东西)?
答案 0 :(得分:1)
成员对于具有相同类型的另一个对象的实例始终是“公开的”。
意味着My<Buddy>
实例(例如me
)可以访问另一个My<Buddy>
实例的私有成员(例如bud
)。
请注意,My<int>
与My<Buddy>
完全不同,因此无法访问这些成员。
答案 1 :(得分:0)
由于play
方法被定义为引用My<Buddy>
而不是My<T>
,因此在My<Buddy>
的另一个实例上调用时,有效类的类型相同。因此,私人会员可以访问。
答案 2 :(得分:0)
与那些假装拥有强大的静态类型系统和泛型(看着你的Java)的语言不同,C ++允许你根据参数(参数通常是类型)来消除静态参数类型(模板类型)的歧义。模仿。
注意:您还可以使用派生(动态/后期绑定)类型作为静态参数化类型的参数,但在此方案中它不相关。
换句话说,在C ++中:
typeid(me) == typeid(bud)
将 TRUE typeid(h) == typeid(me)
将 FALSE 即使“我的”类型相同。
您可以从相同的类型访问私有数据成员,就像它们是公开的一样,但正如您所看到的,第二个比较是假的,因为操作数不属于同一类型,因此违反了该类型的访问限制。
另外,我认为没有办法查看编译器生成的代码。 (据我所知。)