zoukankan      html  css  js  c++  java
  • C++ private访问限制

    了解C++的同学都很清楚,C++有3个访问控制符,提供了对数据的封装,分别是public、protected与private。

    private算是对数据保护得最严实的控制符了,一般都会说到private成员只能被类本身的成员函数以及类的友元访问,其他函数需要访问时,

    大多数会封装一个public的set和get方法进行访问,或者 返回指针与引用也是可以的,但并不推荐,毕竟这样不利于封装的特性,

    当然,下面介绍的方法是进行讨论使用其他方式突破private的访问限制,一般情况下也不会使用。

    那么先从代码开始吧。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 class TestClass
     5 {
     6 public:
     7     TestClass() : m_nA(1), m_nB(2), m_nC(3) {};
     8     ~TestClass() {};
     9     void PrintValue()
    10     {
    11         cout << "m_nA: " << m_nA << "	" << "m_nB: " << m_nB << "	" << "m_nC: " 
    12             << m_nC << endl;
    13     }
    14 private:
    15     int m_nA;
    16     int m_nB;
    17     int m_nC;
    18 };
    19 int main()
    20 {
    21     TestClass Test;
    22     Test.PrintValue();
    23 
    24     cout << "---------------------------------------------------" << endl;
    25     
    26     int nValue = 7;
    27     int* ptr = (int*)(&Test);
    28     *(ptr++) = nValue++;
    29     *(ptr++) = nValue++;
    30     *(ptr++) = nValue++;
    31 
    32     Test.PrintValue();
    33 
    34     return 0;
    35 }

    当声明了一个Test对像时,那么系统将会开辟一段连续的空间,此对象将会有如下的内存布局,如何正确的访问,需要考虑到字节的对齐。

     有了内存空间,当然可以使用指针进行访问,那么强行对此内存地址赋值即可。

    27~30行的操作就是如此。

    简单的总结来说,访问说明信息通常是在编译期间消失,在程序运行期间,对象变成了一个存储区域,别无他物,

    因此,如果有人想破坏这些规则并且直接访问内存中的数据,是很容易的(存在大量的数据,继承时,使用此方法精确的更改数据内容就会变得非常困难),

    C++并不能防止这种不明智的操作,毕竟C++关注的焦点是抽象。

    那么除此之外还有其他方法吗?

    答案是有的

    比如声明另一个classB,只需要在classB中,把classA的private的访问控制符更改为public。

    此时,相应的对象B与对象A的内存布局是一致的,只是访问限制不同,所以可以利用访问对象B的规则去访问对象A。

    一个指向B对象的指针实际指向了一个A对象,对B中public成员变量的访问实际上是对A对象中private成员变量的访问。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 class TestClass
     5 {
     6 public:
     7     TestClass() : m_nA(1), m_nB(2), m_nC(3) {};
     8     ~TestClass() {};
     9     void PrintValue()
    10     {
    11         cout << "m_nA: " << m_nA << "	" << "m_nB: " << m_nB << "	" << "m_nC: " 
    12             << m_nC << endl;
    13     }
    14 private:
    15     int m_nA;
    16     int m_nB;
    17     int m_nC;
    18 };
    19 
    20 class TestClassB
    21 {
    22 public:
    23     TestClassB() : m_nA(11), m_nB(22), m_nC(33) {};
    24     ~TestClassB() {};
    25     void PrintValue()
    26     {
    27         cout << "m_nA: " << m_nA << "	" << "m_nB: " << m_nB << "	" << "m_nC: "
    28             << m_nC << endl;
    29     }
    30 public:
    31     int m_nA;
    32     int m_nB;
    33     int m_nC;
    34 };
    35 
    36 int main()
    37 {
    38     TestClass a;
    39     TestClassB* b = (TestClassB*)&a;
    40     a.PrintValue();
    41     b->m_nA = 6;
    42     b->m_nB = 9;
    43     cout << "m_nA:" << b->m_nA << endl;
    44     cout << "m_nB:" << b->m_nB << endl;
    45     a.PrintValue();
    46     return 0;
    47 }

  • 相关阅读:
    单例模式
    Curator Zookeeper分布式锁
    LruCache算法原理及实现
    lombok 简化java代码注解
    Oracle客户端工具出现“Cannot access NLS data files or invalid environment specified”错误的解决办法
    解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。
    Redis 3.0 Cluster集群配置
    分布式锁的三种实现方式
    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
    How to Use Convolutional Neural Networks for Time Series Classification
  • 原文地址:https://www.cnblogs.com/XavierJian/p/12912660.html
Copyright © 2011-2022 走看看