2

我指的是“用 C++ 思考”一书中提到的练习之一。下面的代码片段会为调用 h.play 引发错误,我理解,因为成员 i 是私有的。但我期待同样的错误打电话给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 编译器标志的东西)?

4

3 回答 3

1

成员对于具有相同类型的另一个对象的实例始终是“公共的”。

这意味着一个My<Buddy>实例(例如)可以访问另一个实例(例如)me的私有成员。My<Buddy>bud

请记住,这My<int>是与 完全不同的类型My<Buddy>,因此它无法访问这些成员。

于 2013-04-02T00:37:11.930 回答
0

因为该play方法被定义为引用My<Buddy>而不是 a My<T>,所以当在 的另一个实例上调用时,有效类是相同的类型My<Buddy>。因此私有成员是可访问的。

于 2013-04-02T00:37:21.520 回答
0

与只是假装具有强大的静态类型系统和泛型(看看你的 Java)的语言不同,C++ 允许你根据类型模板化的参数(参数通常是类型)来消除静态参数类型(模板类型)的歧义。

注意:您还可以使用派生(动态/后期绑定)类型作为静态参数化类型的参数,但在这种情况下不相关。

换句话说,在 C++ 中:

  • typeid(me) == typeid(bud)将是TRUE
  • typeid(h) == typeid(me)将是FALSE

即使类型“我的”是相同的。

您可以从与公共类型相同的类型访问私有数据成员 ,但正如您所见,第二个比较是错误的,因为操作数类型不同,因此您违反了类型的访问限制。

另外,我认为没有任何方法可以查看编译器生成的代码。(据我所知。)

于 2013-04-02T01:03:24.463 回答