C++突破private的方案

   日期:2020-07-03     浏览:91    评论:0    
核心提示:C++突破private的方案文章目录C++突破private的方案方法一:调用公共成员函数方法二:友元函数方法三:使用 指针与引用访问方法四:指针的类型装换方法五:利用模版合法方法一:调用公共成员函数#include using namespace std;class X {private: int a; int b; public: X(): a(3), b(4) {} int geta()

C++突破private的方案

文章目录

  • C++突破private的方案
    • 方法一:调用公共成员函数
    • 方法二:友元函数
    • 方法三:使用 指针与引用访问
    • 方法四:指针的类型装换
    • 方法五:利用模版合法

方法一:调用公共成员函数

#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X(): a(3), b(4)
    {}
    
    int geta()
    {
        return a;
    }
    
    void seta(int x)
    {
        a = x;
    }
    
    int getb()
    {
        return b;
    }
    void setb(int x)
    {
        b = x;
    }
    
    friend int setgetbx(X &,int x);
};

int main()
{
    X s = X;
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;
    
    s.seta(10);
    s.setb(10);
    cout<<"reset a="<<s.geta()<<endl;
    cout<<"reset b="<<s.getb()<<endl;
    return 0;
}

方法二:友元函数

#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X()
    : a(3), b(4)
    {}
    
    int geta()
    {
        return a;
    }
    
    int getb()
    {
        return b;
    }
    
    friend int setgetbx(X & x,int temp);// 类内声明友元函数
};

// 类外定义友元函数
int setgetbx(X & x,int temp)
{  							
    x.b += temp;
    return x.b;
}

int main()
{
    X s = X();
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;

    int newb = setgetbx(s,5);	//调用友元函数
    cout<<"reset b="<<newb<<endl;
    cout<<"reset b="<<s.getb()<<endl;
    return 0;
}

方法三:使用 指针与引用访问

#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X()
    : a(3), b(4)
    {}
    
    int geta()
    {
        return a;
    }
    
    int getb()
    {
        return b;
    }
};

int main()
{
    X s = X;
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;
    
    int *ptr = (int *)(&s); // 强转类指针
    cout<<"init a="<<*ptr<<endl;
    cout<<"init b="<<*(ptr+1)<<endl;
    
    //注意因为类当中刚好只有两个int类型的变量,如果有其他情况把指针后移对应大小即可
    *ptr = 5;//指向a
    *(ptr + 1) = 5;// 指向b
    cout<<"pointer reset a="<<s.geta()<<endl;
    cout<<"pointer reset b="<<s.getb()<<endl;
    return 0;
}


方法四:指针的类型装换

  • X与Y 里面的成员变量x.a x.b的位置一一对应
#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X()
    : a(3), b(4)
    {}
    
    int geta()
    {
        return a;
    }
    
    int getb()
    {
        return b;
    }
};

class Y
{
public:
    int a;	//与 X里面a对应
	int b;	//与 X里面b对应
};

void Func(X* xPtr)
{
	// reinterpret_cast 用于进行各种不同类型的指针之间、
	// 不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。
	(reinterpret_cast<Y*>(xPtr))->b = 2;
}

int main()
{
    X s = X;
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;
    
    Func(&s);
    Func(&s);
    //cout<<"reinterpret_cast reset a="<<s.geta()<<endl;
    cout<<"reinterpret_cast reset b="<<s.getb()<<endl;
    return 0;
}

  • 如果不对齐的话看下面一个实验
#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X()
    : a(3), b(4)
    {}
    
    int geta()
    {
        return a;
    }
    
    int getb()
    {
        return b;
    }
};

class Y
{
public:
	int b;
};

void Func(X* xPtr)
{
	// reinterpret_cast 用于进行各种不同类型的指针之间、
	// 不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。
	(reinterpret_cast<Y*>(xPtr))->b = 2;
}

int main()
{
    X s = X;
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;
    
    Func(&s);	//attention
    cout<<"reinterpret_cast reset a="<<s.geta()<<endl;
    cout<<"reinterpret_cast reset b="<<s.getb()<<endl;
    return 0;
}

  • 此时修改Y的b 但是确实修改X里面的a,这是因为 Y的b 与X的啊 在类内具有相同的内存位置,归根究低还是对指针与实际内存的操作

方法五:利用模版合法

#include <iostream>
using namespace std;

class X 
{
private:
    int a;
    int b;
    
public:
    X()
    : a(3), b(4)
    {}
    
    template<typename T>//在X类内定义成员模板函数
	void Func(const T &t){}
	
    int geta()
    {
        return a;
    }
    int getb()
    {
        return b;
    }
};

//外部Y类
class Y 
{};
 												
template<>
void X::Func(const Y&) //特化,attention 
{
	a=2;
	b=8;
}

int main()
{
    X s = X;
    cout<<"init a="<<s.geta()<<endl;
    cout<<"init b="<<s.getb()<<endl;
    
    s.Func(Y());//attention
    cout<<"template reset a="<<s.geta()<<endl;
    cout<<"template reset b="<<s.getb()<<endl;
    return 0;
}

这种方法利用了X具有一个成员模板的事实,通过特化函数模版,来打入敌人内部。代码完全符合标准,标准也确保这种行为会按照编码者的意图行事。boost和loki中大量运用此手法

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服