c++访问私有private成员变量的常用方法

 更新时间:2020年08月20日 11:51:37   作者:Hao_09  
这篇文章主要介绍了c++访问私有private成员变量的常用方法,需要的朋友可以参考下

类的对象不能直接访问类声明的私有成员变量,否则破坏了信息隐藏的目的。

在C++中,为了防止某些数据成员或成员函数从外部被直接访问,可以将它们声明为private,这样编译器会阻止任何来自外部非友元的直接访问。

私有成员变量的常用访问方法如下:

(1)通过公共函数为私有成员赋值

#include <iostream> 
using namespace std; 
 
class Test 
{ 
private: 
	int x, y; 
public: 
	void setX(int a) 
	{ 
		x=a; 
	} 
	void setY(int b) 
	{ 
		y=b; 
	} 
	void print(void) 
	{ 
		cout<<"x="<<x<<'\t'<<"y="<<y<<endl; 
	} 
} ; 
 
int main() 
{ 
	Test p1; 
	p1.setX(1); 
	p1.setY(9); 
	p1.print( ); 
	return 0; 
} 

(2)利用指针访问私有数据成员

#include <iostream> 
using namespace std; 
class Test 
{ 
private: 
	int x,y; 
public: 
	void setX(int a) 
	{ 
		x=a; 
	} 
	void setY(int b) 
	{ 
		y=b; 
	} 
	void getXY(int *px, int *py) 
	{ 
		*px=x; //提取x,y值 
		*py=y; 
	} 
}; 
int main() 
{ 
	Test p1; 
	p1.setX(1); 
	p1.setY(9); 
	int a,b; 
	p1.getXY(&a,&b); //将 a=x, b=y 
	cout<<a<<'\t'<<b<<endl; 
	return 0; 
} 

(3)利用函数访问私有数据成员

#include <iostream> 
using namespace std; 
class Test 
{ 
private: 
	int x,y; 
public: 
	void setX(int a) 
	{ 
		x=a; 
	} 
	void setY(int b) 
	{ 
		y=b; 
	} 
	int getX(void) 
	{ 
		return x; //返回x值 
	} 
	int getY(void) 
	{ 
		return y; //返回y值 
	} 
}; 
int main() 
{ 
	Test p1; 
	p1.setX(1); 
	p1.setY(9); 
	int a,b; 
	a=p1.getX( ); 
	b=p1.getY(); 
	cout<<a<<'\t'<<b<<endl; 
	return 0; 
} 

(4)利用引用访问私有数据成员

#include <iostream> 
using namespace std; 
class Test 
{ 
private: 
	int x,y; 
public: 
	void setX(int a) 
	{ 
		x=a; 
	} 
	void setY(int b) 
	{ 
		y=b; 
	} 
	void getXY(int &px, int &py) //引用 
	{ 
		px=x; //提取x,y值 
		py=y; 
	} 
}; 
int main() 
{ 
	Test p1,p2; 
	p1.setX(1); 
	p1.setY(9); 
	int a,b; 
	p1.getXY(a, b); //将 a=x, b=y 
	cout<<a<<'\t'<<b<<endl; 
	return 0; 
}

下面是其它网友的补充

访问C++类对象中私有成员变量的方法

原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,但如果没有get、set方法都没有提供,比如使用的是第三方提供的.o(或者动态库)来进行开发的,并且实际应用中我们确确实实需要改变其中某个对象的一个私有参数,有没有什么办法呢?我们知道,一个进程有程序段和数据段,如果我们知道了对象的数据空间,那么得到该对象的成员变量值也就很简单了,而实际上,对象数据段的首地址其实就是对象地址,以例子说明:

class A
{
public:
 int i;
 bool setJ(int _j){j = _j;};
 int getJ() const {return j;};
private:
 int j;
};

int main()
{
 A a;
 printf("a's address is %u.n",&a); // 打印对象a的地址
 printf("a.i's address is %u.n",(&(a.i))); // 打印对象a的成员变量i的地址
}

执行上面程序,可以看到结果,两个值时一样的,也就是说明对象地址就是第一个成员变量的地址。
我们知道,C++编译器将数据和程序段分开,所有的类变量会按照声明顺序依次存入数据段,所以,如果知道了第一个变量的地址,那么后面的地址也就依次累加即可逐一求出了。有了变量地址,那么也就可以对它的值进行修改了。还是以上面的例子来说明,一下程序编写了如何更改类成员b的值:

int main()
{
 A a;
 a.setJ(2);
 printf("before modified:the member j of a is %d.n",a.getJ()); // 打印j的值。
 int *p = (int *)(int(&a) + sizeof(a.i));
 *p = 10;
 printf("after modified:the member j of a is %d.n",a.getJ()); // 打印j的值。
}

可以得出此时j成员变量的值由2变成10了。

总结:直接对地址空间操作,请小心为妙。。。 

此外,另附一篇与此类似的文章,也很有启发性。

分析程序员和黑客的区别

 题目:
  设有如下C++类

class A
{
 int value;
public:
 A(int n = 0) : value(n) {}
 int GetValue()
 {
 return value;
 }
};

请使用某种方式来在类的外部改变私有成员A::value的值。

程序员的可能做法:

class A
{
 int value;
public:
 A(int n = 0) : value(n) {}
 int GetValue()
 {
 return value;
 }
 void SetValue(int n)
 {
 value = n;
 }
};
void f()
{
 A a;
 a.SetValue(5);
}

黑客的可能做法:

void f()
{
 A a;
 *((int *)&a) = 5;
}

结论:

程序员习惯于遵循既有的限制来增加既有的东西。
黑客习惯于利用既有的东西来打破既有的限制。

到此这篇关于c++访问私有private成员变量的常用方法的文章就介绍到这了,更多相关c++私有private成员变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt实现Flappy Bird游戏

    Qt实现Flappy Bird游戏

    这篇文章主要为大家详细介绍了Qt实现Flappy Bird游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • C++函数重载的深入解析

    C++函数重载的深入解析

    在C++中,我们也能够把具有相同功能的函数整合到一个函数上,而不必去写好多个函数名不同的函数,这叫做函数的重载。以下是对C++中的函数重载进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-07-07
  • 谈谈vector的特殊性之为什么它不是STL容器

    谈谈vector的特殊性之为什么它不是STL容器

    这篇文章主要给大家介绍了关于vector的特殊性之为什么它不是STL容器的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • 标准CSV格式的介绍和分析以及解析算法实例详解

    标准CSV格式的介绍和分析以及解析算法实例详解

    这篇文章主要介绍了标准CSV格式的介绍和分析以及解析算法实例详解的相关资料,需要的朋友可以参考下
    2016-12-12
  • C语言WinSock学习笔记

    C语言WinSock学习笔记

    本篇文章主要介绍了C语言WinSock学习笔记,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2007-12-12
  • c++函数中的指针参数与地址参数区别介绍

    c++函数中的指针参数与地址参数区别介绍

    c++函数中的指针参数与地址参数区别介绍;可供参考
    2012-11-11
  • 基于C++实现一个简单的音乐系统

    基于C++实现一个简单的音乐系统

    C++中的Beep 函数是一个发出嗡鸣声的函数,本文将利用这个函数实现制作一个简单的声音系统。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-12-12
  • c++运算符重载基础知识详解

    c++运算符重载基础知识详解

    运算符重载是一种形式的C++多态。运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义
    2014-03-03
  • 线程池的原理与实现详解

    线程池的原理与实现详解

    下面利用C语言来实现一个简单的线程池,为了使得这个线程池库使用起来更加方便,特在C实现中加入了一些OO的思想,与Objective-C不同,它仅仅是使用了struct来模拟了c++中的类,其实这种方式在linux内核中大量可见
    2013-09-09
  • C++改变参数值的方式小结

    C++改变参数值的方式小结

    本文主要介绍了C++改变参数值的方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04

最新评论