关于C++实现类外不能访问私有数据的理解

        最近在写简单的写点练手的代码,其中有一个就是自己写一个String类,能够实现构造函数、赋值构造函数、符号函数重载以及析构函数。顺便提一句,这个问题如果作为面试应届生的话,还是很不错的一个问题。代码如下:

class ZString
{
private: 
	char* pc_buf;

public:
	ZString(const char *pcbuf);
	ZString(const ZString &sZstring);
	~ZString();
	ZString operator=(const ZString sZstring);
	void OutPut();
};

ZString::ZString(const char *pcbuf)
{
	if(NULL != pcbuf)
	{
		pc_buf = (char *)malloc(strlen(pcbuf) + 1);
		memcpy(pc_buf, pcbuf, strlen(pc_buf) +1);
	}
}

ZString::ZString(const ZString &sZstringVal)
{
	if (NULL != sZstringVal.pc_buf)
	{
		pc_buf = (char *)malloc(strlen(sZstringVal.pc_buf) + 1);
		memcpy(pc_buf, sZstringVal.pc_buf, strlen(sZstringVal.pc_buf) + 1);
	}
}
ZString::~ZString()
{
	if (NULL != pc_buf)
	{
		free(pc_buf);
		pc_buf = NULL;
	}
}
ZString ZString::operator=(const ZString sZstring)
{
	ZString zTem(sZstring.pc_buf);
	return zTem;
}
void ZString::OutPut()
{
	cout << pc_buf << endl;
}

其实整个代码非常简单,但是有一点比较有意思,就是在重载函数里面,有这样一句代码:

ZString ZString::operator=(const ZString sZstring)
{
	ZString zTem(sZstring.pc_buf);
	return zTem;
}

可以看到,我实现了对象.私有数据的直接调用。如果这要是在main函数里面是绝对不会被允许的,但是在类内就可以调用。网上查了一下,很多人都说私有数据是在类内可以访问的,类外无法访问,哪怕是类内可以访问其对象的私有数据也可以。然后我的问题又来了,这个功能是怎么实现的呢?怎么做到类外是无法访问的呢?答案也比较简单:编译器。其实就是在编译器进行处理的时候不让你在类外调用能编译通过。原因有两个:1、如果你访问了,去编译代码的时候直接编译报错,而不是链接或者运行的时候出现问题。2、其实你可以绕过编译器,代码功能仍然是可以访问呢,比如如下:

class ZClass
{
private:
	char szArray[10];


public:
	void GetMemberAddrByPoint(char *&c);
	char* GetMemberAddrByFunc();
	void InitClass();
};

//直接把私有数据的地址赋值给一个变量
void ZClass::GetMemberAddrByPoint(char *&c)
{
	c = szArray;
}

//直接返回地址
char* ZClass::GetMemberAddrByFunc()
{
	return szArray;
}

void ZClass::InitClass()
{
	for(int i = 0; i < 10; i++)
	{
		szArray[i] = 'a'+ i;
	}
}

int main()
{
	
	ZClass cTestClass;
	cTestClass.InitClass();
	char *point = cTestClass.GetMemberAddrByFunc();
	cout << point[1] << endl;
	char *point2;
	cTestClass.GetMemberAddrByPoint(point2);
	cout<< point2[2] <<endl;
}

可以看到上面的代码,其实只要是把私有数据的地址给拿出来,你是可以访问的,也是可以操作的。这个就说明私有数据的内存其实没有什么特殊的地方,只是编译器限制罢了。这个的原理应该是和const里面是一样的。你把一个变量加上了const,这个变量是不能被修改了,但是如果你把这个变量的地址取出来再重新操作,仍然是可以的。所以我一直以为这种很多规则和逻辑是在内存里面实现的,其实不是的。本质上都是在编译器上产生的,这个想明白了也就没有那么玄乎了。

好了,今天就到这里吧。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值