由private成员到类成员访问控制

众所周知,C++类强调密封性,每个类的成员分为公共成员、私有成员与保护成员。而很多人会跟我一样,在学C++的时候就有一种与之俱来的感觉,动态私有成员只能由此对象的成员函数或者友元读取修改,不能由此之外其他方式直接访问。

#include <iostream>
 
using namespace std;
 
class ClassA
{
private:
    int num;
public:
    ClassA(int n =100)
    {
        num = n;
    }
    void ShowNumber()
    {
        cout <<"num = " << num << endl;
    }
};
 
int main()
{
    ClassA a;
    a.ShowNumber();
    return 0;
}


而代码中的A.b,大家都知道是无法在对象以外的地方直接访问到的

很多人在写拷贝函数的时候,会这样写。

#include <iostream>
 
using namespace std;
 
class ClassA
{
private:
    int num;
public:
    ClassA(int n =100)
    {
        num = n;
    }
    A(const ClassA &a)
    {
        num=a.num;
    }
    void ShowNumber()
    {
        cout <<"num = " << num << endl;
    }
};
 
int main()
{
    ClassA a;
    ClassA b(a);
    a.ShowNumber();
    b.ShowNumber();
    return 0;
}


可是,大家有没有考虑过,这两个概念是冲突的。拷贝函数可以访问另外一个实例的私有成员。于是乎我们可以这样写。难道这是与拷贝函数有关么?

#include <iostream>
 
using namespace std;
 
class ClassA
{
private:
    int num;
public:
    ClassA(int n =100)
    {
        num = n;
    }
    ClassA(const ClassA &a)
    {
        num=a.num;
    }
    void GetNumber(const ClassA &class1)
    {
       int a=class1.num;
       cout<<"the number is "<<a<<endl;
    }
    void ShowNumber()
    {
        cout <<"num = " << num << endl;
    }
};
 
int main()
{
    ClassA a(1000);
    ClassA b(89);
    a.ShowNumber();//a的b
    b.ShowNumber();//b的b
    a.GetNumber(b);//尝试读取b的b
    return 0;
}


运行结果为

num=1000

num=89

the number is 89

成功,我们成功读取了另一个实例的私有成员。证明这与拷贝函数无关。

再修改一下,我们尝试下修改那个实例的私有成员。

#include <iostream>
 
using namespace std;
 
class ClassA
{
private:
    int num;
public:
    ClassA(int n =100)
    {
        num = n;
    }
    ClassA(const ClassA &a)
    {
        num=a.b;
    }
    void GetNumber(const ClassA &class1)
    {
       int a=class1.num;
       cout<<"the number is "<<num<<endl;
    }
    void SetNumber(ClassA &class1,int n)
    {
       class1.num = n;
    }
    void ShowNumber()
    {
        cout <<"num = " << num << endl;
    }
};
 
int main()
{
    A a(1000);
    A b(89);
    a.ShowNumber();//a的b
    b.ShowNumber();//b的b
    a.GetNumber(b);//尝试读取b的b
    a.SetNumber(b,7);//尝试修改b的b
    a.GetNumber(b);//查看b的b现在是多少
    return0;
}


运行结果为

num=1000

num=89

the number is 89

the number is 7

还是成功了!这难道是编译器的问题么,或者是语法漏洞么。
于是我在ISO/IEC 14882:2003(C++标准文件)中搜索Member access control(成员访问控制),发现以下内容:


11 Member access control [class.access]
1 A member of a class can be
— private; that is, its name can be used only by members and friends of the class in which it is
declared.
— protected; that is, its name can be used only by members and friends of the class in which it is
declared, and by members and friends of classes derived from this class (see 11.5).
— public; that is, its name can be used anywhere without access restriction.


ngdik.com

Private成员的定义是可以被此类的成员以及友元访问。标准中成员访问控制说的是class(类),而我们平时根深蒂固地思想是基于object(对象)的。对象是类的实例,而且,我们可以在类中定义特定的成员函数,去访问此类的另一个实例的私有成员数据以及函数。

虽说这样有可能破坏了C++中类所强调的封装性,不过C++的封装性也是强调而不是对象。可能这也是无奈之举。毕竟,如果没这样的设定的话,拷贝函数该如何去写呢?这也不该我们纠结,不过,这个语法技巧在特定情况下还是能方便我们的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值