2011年3月3日 星期四

friend class

最近有個需求,必須寫一個 Library 供合作廠商使用,
Libray 的內容有關於公司的機密,所以不能任意讓其他人存取,

有一個方法是撰寫成 static function 供人使用,但不美觀,使用上也欠直觀,
於是將腦筋動到 friend 關鍵字上面,
我們可以創造一個存放機密資料的 class
該 class 內不能讓其他人取用的成員就設為 private
再將同一個 Library 中需要操作這些成員的類別設為 friend class
如此可以達到我方便利操作,其他廠商沒辦法取值也無法設值的效果,簡單範例如下

FriendSample.h

/***************** FriendSample.h *****************/

namespace Company
{
  class Boss
  {
    // Boss have 2 Friend
    friend class BadRD;
    friend class BadSales;
  private:
    int m_nMoney;
  };

  class BadRD
  {
  public:
    int ReturnMoney();
  };

  class BadSales
  {
  public:
    int ReturnMoney();
  };
}

namespace Home
{
  using namespace Company;
  class BadSales
  {
  public:
    int ReturnMoney();
  };
}


FriendSample.cpp

/***************** FriendSample.cpp *****************/

int Company::BadRD::ReturnMoney()
{
  Boss boss;
  boss.m_nMoney = 33;
  return boss.m_nMoney;
}

int Company::BadSales::ReturnMoney()
{
  Boss boss;
  boss.m_nMoney = 66;
  return boss.m_nMoney;
}

int Home::BadSales::ReturnMoney()
{
  Boss boss;
  //boss.m_nMoney = 99; // error C2248: 無法存取 private 成員
  //return boss.m_nMoney; // error C2248: 無法存取 private 成員
  return 0;
}

int main(int argc, char *argv[])
{
  Company::Boss boss;
  Company::BadRD badRd;
  Company::BadSales badSales;
  //boss.m_nMoney = 55; // error C2248: 無法存取 private 成員
  cout << badRd.ReturnMoney() << endl; // echo 33;
  cout << badSalesd.ReturnMoney() << endl; // echo 66;
  return 0;
}


建立兩個命名空間是因為有前輩提出要求,要多想一下有沒有其他漏洞可鑽,
目前我想到的是取一個同名的 class 來操作朋友的 private 成員,
同一個 namespace 下當然無法存在兩個同名的 class 宣告,
所以使用兩個 namespace 測試看看,結果在不同 namespace 下是無法操作的(這很直觀),
方法也許很迂迴很笨,但目前只想到用 friend 來達到這種效果,未來有更好更直觀的方法再記上…

沒有留言:

張貼留言