C++ 如何突破private成員的訪問限制
阿新 • • 發佈:2018-12-26
c++中類的private成員對外是不可見的,以下方法可以突破private成員的訪問許可權。
// accessPrivateMember.h
class A
{
private:
int mPrivate;
int nPrivate;
public:
A(): mPrivate(3), nPrivate(4){}
template<typename T> void func(const T &t){}
const int GetValueN()
{
return nPrivate;
}
};
1、操作指標修改記憶體資料
#include <iostream>
#include "accessPrivateMember.h"
int main()
{
A obj = A();
int tmp = 7;
int *ptr = (int *)(&obj);
*(ptr+1) = tmp;
std::cout<<"nPrivate: "<<obj.GetValueN()<<std::endl;
return 0;
}
2、使用友元宣告
在類內宣告一個友元函式,在類外進行定義。
#include <iostream>
class A
{
private:
friend void hiJack(A &);
int mPrivate;
int nPrivate;
public:
A(): mPrivate(3), nPrivate(4){}
template<typename T> void func(const T &t){}
const int GetValueN()
{
return nPrivate;
}
};
void hiJack(A &a)
{
a.nPrivate = 2;
}
int main()
{
A obj = A();
hiJack(obj);
std::cout<<"nPrivate: "<<obj.GetValueN()<<std::endl;
return 0;
}
3、使用模板
類A中定義了一個模板函式func,在類外加一個模板函式,導致模板推演的過程中多出一個自己寫的並且加入了備選組中,相當於多了一個過載。
類外函式的引數是在匿名空間中定義的特定型別,所以避免擾亂原本該函式的功能。
#include <iostream>
#include "accessPrivateMember.h"
namespace {struct B{};} // struct member default public
template<> void A::func(const B &)
{
nPrivate = 2;
}
int main()
{
A obj;
obj.func(B());
std::cout<<"nPrivate: "<<obj.GetValueN()<<std::endl;
return 0;
}
4、#define private public
使用#define把private定義為public,這樣類中定義的private起始就是public。不推薦使用這種方法。
5、使用指標型別轉換
在linux g++下試驗的時候,發現這種方法沒有生效,nPrivate的值仍然為4。原因需要後續研究...
#include <iostream>
#include "accessPrivateMember.h"
class B
{
public:
int nPrivate;
};
void funa(A *aPtr)
{
(reinterpret_cast<B*>(aPtr))->nPrivate = 2;
}
int main()
{
A obj = A();
funa(&obj);
std::cout<<"nPrivate: "<<obj.GetValueN()<<std::endl;
return 0;
}