Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56684
  • 博文数量: 9
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-14 22:57
个人简介

沧海之一粟

文章分类

全部博文(9)

文章存档

2015年(2)

2014年(7)

我的朋友

分类: C/C++

2014-05-28 17:54:15

下面以私有(private)成员为例,来说明C++是如何实现访问控制的。

在C++中,私有成员的
只能被这些成员所在的类的内部成员函数和友元访问。
之所以强调”名称“是因为,C++的访问控制实际上是通过限制对名称的使用来实现的。
成员的名称既可以表示函数,也可以是数据成员,类型,常量等,跟名称表示的对象无关。
只要这些成员是属于这个类的,那么对成员名称的使用,就要受到C++的访问控制规则的约束。

在此,通过以下例子来说明问题:
如果在类中定义了一个私有的非静态类型,但是有个一在类的外部实现的成员函数,把这个私有类型当做其返回值。
那么这样做对吗?假如对,能在类的外面访问这个私有类型的public数据成员吗?

  1. #include <iostream>

  2. using namespace std;

  3. class Link
  4. {
  5. private:
  6.     struct Node
  7.     {
  8.         Node(int d)
  9.         {
  10.             data = d;
  11.             prev = nullptr;
  12.             next = nullptr;
  13.         }
  14.         int data;
  15.         Node *prev;
  16.         Node *next;
  17.     };

  18.     Node *first;
  19.     Node *last;
  20. public:
  21.     Link()
  22.     {
  23.         first = nullptr;
  24.         last = nullptr;
  25.     }

  26.     ~Link()
  27.     {
  28.         Node *n1 = first, *n2;
  29.         while (n1)
  30.         {
  31.             n2 = n1->next;
  32.             delete n1;
  33.             n1 = n2;
  34.         }
  35.     }

  36.     void Append(int d)
  37.     {
  38.         Node *n = new Node(d);
  39.         if (first)
  40.         {
  41.             n->prev = last;
  42.             last->next = n;
  43.             last = n;
  44.         }
  45.         else
  46.         {
  47.             first = n;
  48.             last = first;
  49.         }
  50.     }

  51.     Link::Node* First();
  52. };

  53. Link::Node* Link::First()
  54. {
  55.     return first;
  56. }

  57. int main(int argc, char* argv[])
  58. {
  59.     Link l1;
  60.     l1.Append(100);
  61. //  正确!并没有在类的外部使用私有成员的名称。编译器是通过类型推理得知n1的类型的。
  62.     auto *n1 = l1.First();
  63. //  错误!不能在类的外部使用私有成员的名称。
  64. //  Link::Node * n1 = l1.First();
  65.     cout << n1->data << endl;
  66.     return 0;
  67. }
输出结果为:
100

由以上例子说明,即使是私有类型,也可以作为类的public成员函数的返回值。
再来分析原因:
1,因为First函数是Link类的成员函数。并没有违反private访问控制规则(私有成员,可以被相同类内部的成员函数和友元访问)。
First和Node同属Link类,并且Node属于First函数成员签名的一部分,所以定义(或声明)返回私有成员的成员函数是合法的。
2,如果将main函数中auto *n1 = l1.First();修改为Link::Node *n1 = l1.First();,则会出现编译错误。
原因就是上面提到的,C++是通过限制对名称的使用来实现访问控制的。使用auto并没有违反规则,因为确实没有在类的外部使用私有成员的名称。
C++编译器通过类型推理,得知n1的类型是Link::Node*,data属于Node的public成员,所以是可以访问的。



阅读(1955) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~