程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++中類的數據成員的安全隱患

C++中類的數據成員的安全隱患

編輯:關於C++

在任何一本關於"C++語言程序設計"的書中都有類似於如下的描述:

在一個類中,C++用三個關鍵詞設置訪問界限:public, private和protected。它們決定了跟在他們後面的標識符的被使用情況:public意味著其後的標識符可以被用戶定義的其實例引用;而private則說明其後的標識符除了類的成員函數之外,用戶定義的其實例不能引用;protected為類的繼承提供了接口,同時保護其不被外界訪問。

事實上也,如果要想利用類的一個對象(或實例)來訪問其成員時確實如此。但是,在C++中,由於容許將指針類型進行任意轉換,從而給用戶提供了一個"穿越保護屏障"的方法。這可以從以下的例程中看到:

#include
class CMyClass{
  double d;
  int x,y;
  const char ch;
public:
  int z;
  CMyClass(int xx,int yy,char c):ch(c){x=xx,y=yy;d=9.8759;z=0;}
  void Show(){
    cout<<"d="<<d<<" "<<"x="<<x<<" "<<"y="<<y<<" "<<"ch="<<ch<<" ";
    cout<<"z="<<z<<endl;  }
};
void main()
{
  cout<<sizeof(CMyClass)<<endl;
  CMyClass p(1,2,''U'');
  p.Show();
  CMyClass *ptr=&p;
//   ptr->x=9.32145; //錯誤,因為x是其私有成員,外部不能直接訪問。
  double*dP=(double*)ptr; //獲取了p.d的地址
  *dP=9.32145; //修改p.d的值
  int*iP=(int*)(dP+1); //獲取了p.x的地址
  *iP=300; //修改p.x的值
  *(iP+1)=200; //修改p.y的值
  *(iP+2)=65; //修改ch的值變為''A'',但ch是常數!
  *(iP+3)=100; //修改p.z的值
  p.Show();
}
運行結果如下:
**********************************************
24
d=9.8759 x=1 y=2 ch=U z=0
d=9.32145 x=300 y=200 ch=A z=100
**********************************************

類CMyClass中有四個私有成員double d、int x,y與const char ch,通過其對象p肯定是不能察看或修改其值的,但是利用指向對象p的指針ptr我們做到了。利用將ptr轉換成double* dP修改了d的值,然後再將dP轉化成int*iP修改了其余所有數據成員的值。從以上的結果還看出char在類中占有與int相同大小的內存,這是因為類的alignment(邊緣調整)引起的。一個更糟糕的事情是ch的值也被修改了!它可是一個const!!pointer is a god!它真是無所不能!!

指針的"不安全"性在此例中得到了充分的展示,應該對它進行限制!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved