如何破壞C++的訪問控制

滕瑞發表於2015-03-19

封裝,繼承和多型是物件導向的三大特徵。其中封裝是利用設定訪問控制許可權來實現的。在C++中,訪問控制許可權可以用友元、巨集和型別轉換等方法來破壞。這裡介紹一下巨集和型別轉換的方法。

首先定義一個包含私有成員的類Employee,居然沒有定義加薪的介面,擺明不想給漲工資!(employee.h)

class Employee 
{
public:
    Employee(int salary) : salary(salary) {}
    int getSalary()
    {
        return salary;
    }
private:
    int salary;
};

既然老闆不想給加薪,只有自己動手了。首先使用巨集定義#define private public方法(main.cpp):

#include <iostream>

#define private public
#include "employee.h"
#define private private

using namespace std;

int main()
{
    Employee p = Employee(10000);
    cout << "Original salary: $" << p.getSalary() << endl;

    p.salary = 20000;
    cout << "Current salary: $" << p.getSalary() << endl;

    return 0;
}

執行結果:

Original salary: $10000
Current salary: $20000
請按任意鍵繼續. . .

另外還能用強制型別轉換reinterpret_cast的方法。首先定義一個結構相同的類,注意把salary定義為public訪問許可權。(hacker.h):

class Hacker 
{
public:
    Hacker(int salary) : salary(salary) {}
    int getSalary()
    {
        return salary;
    }
public:
    int salary;
};

然後使用如下方法(main.cpp):

#include <iostream>
#include "employee.h"
#include "hacker.h"

using namespace std;

int main()
{
    Employee p = Employee(10000);
    cout << "Original salary: $" << p.getSalary() << endl;

    Hacker *h = reinterpret_cast<Hacker*>(&p);
    h->salary = 20000;
    cout << "Current salary: $" << p.getSalary() << endl;

    return 0;
}

執行結果同樣為:

Original salary: $10000
Current salary: $20000
請按任意鍵繼續. . .

結論:

  1. C++的訪問許可權並不完備,可以通過友元、巨集和強制型別轉換等方法破壞。
  2. 參考第一條。

相關文章