C++对象的私有成员是禁止类外的访问的。但是我们仍然可以通过指针访问C++对象的私有成员。

#include <iostream>
using namespace std; class A
{
public:
A(int i = )
:m_i(i)
{}
void print()
{
cout << "m_i" << this->m_i << endl;
}
private:
int m_i;
}; int main(int argc, char **argv)
{
A a();
// 初始化后的a的私有变量是10
a.print(); //可以通过指针访问a中的m_i变量
int *pi = (int *)&a;
cout << "a::m_i: " << *pi << endl; //通过指针更改m_i
*pi = ;
//我们看到对象a中的私有变量m_i已经被改变
a.print();
return ;
}

运行结果:

m_i:
a::m_i:
m_i:

在上面代码中,a对象有一个私有的数据成员m_i,原则上在类外部是不能对m_i进行访问的。但是我们可以通过地址访问对象的私有数据成员m_i。并且还对其进行了修改。运行结果也表明我们确实可以通过指针访问对象的私有成员并且可以对其进行修改。

究其原因,在C++中访问对象的数据成员,可以根据数据在对象中的偏移地址访问。C++的对象其实就是一个指针数组。这个指针数组存放的是对象的虚函数表和数据成员的地址,我们当然可以通过指针访问对象的任何成员。我想着可能是C++为了兼容C语言而留下的一些不是很安全的做法。

通过指针访问C++对象的私有成员的更多相关文章

  1. C++之在类内部访问对象的私有成员

    一.引言 今天看项目里的一段代码发现,竟然可以再类的成员函数中访问该类的对象的私有成员.感觉不可思议. 自己写的实例代码: #include <iostream> using namesp ...

  2. C++中内部类访问外部类的私有成员

    首先,如果不知道什么是内部类InnerClass的话,就没必要往下看了. 尝试在C++中模仿apple objective-c 的Grand Dispatch简化多线程编程时,使用了boost::fu ...

  3. C#箴言之用属性来访问类的私有成员

    在程序中,难免要访问某个对象的私有成员.那么以前实现这类功能的方法有两种,第一种方法最简单,就是把成员访问符从“private”改为“public”即可:而另一个就是提供公有的成员访问函数来进行访问. ...

  4. CPP-基础:关于私有成员的访问

    a.C++的类的成员函数中,允许直接访问该类的对象的私有成员变量. b.在类的成员函数中可以访问同类型实例的私有变量. c.拷贝构造函数里,可以直接访问另外一个同类对象(引用)的私有成员. d.类的成 ...

  5. 父类指针指向子类内存,为什么当父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数

    我认为是这样,类的成员函数都在代码区,不同的类的成员函数在代码区有自己的类名称空间限制,类的虚函数在虚函数表中,程序执行的时候,是先在虚函数表中找该成员函数,如果没有找到,就去该类在代码区的成员函数中 ...

  6. C#中访问私有成员

    首先访问一个类的私有成员不是什么好做法.大家都知道私有成员在外部是不能被访问的.一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员造访,可以套用下面这种非常好的方式去解决. pr ...

  7. 使用C#反射机制访问类的私有成员【转】

    首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...

  8. c++中嵌套类,外部类访问内部类的私有成员变量

    在嵌套类中,内部类可以直接访问外部类的私有成员变量,但是外部类不能直接访问内部类的私有成员变量,必须把外部类声明为内部类的友元类 /********************************** ...

  9. C#中访问私有成员--反射

    首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...

随机推荐

  1. sql 列集合转换成逗号分隔的字符类型

    CREATE function [dbo].[getGroupPath](@groupId int) returns nvarchar(2000) as begin declare @path nva ...

  2. 软件架构自学笔记-- 转载“虎牙在全球 DNS 秒级生效上的实践”

    虎牙在全球 DNS 秒级生效上的实践 这次分享的是全球 DNS 秒级生效在虎牙的实践,以及由此产生的一些思考,整体上,分为以下 5 各部分: 背景介绍: 方案设计和对比: 高可用: 具体实践和落地: ...

  3. Moto P30(XT1943-1) 免解锁BL 免rec 保留数据 Magisk Xposed ROOT 救砖 ZUI 4.0.374

    >>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...

  4. Android通过透明度设置背景变暗

    变暗 WindowManager.LayoutParams lp=getWindow().getAttributes(); lp.alpha=0.3f; getWindow().addFlags(Wi ...

  5. [Android]有关外部链接唤醒App需要注意的坑

    移动互联网发展到今天,一个移动app需要和各种各样的外部链接关联,它不再仅仅从手机的桌面启动,更多的将会从其他的应用.浏览器链接.短信.二维码或者微信分享等渠道启动,这里涉及到的是各种各样的营销渠道和 ...

  6. JS——事件冒泡与捕获

    事件冒泡与事件捕获 1.冒泡:addEventListener("click",fn,false)或者addEventListener("click",fn): ...

  7. python网络编程调用recv函数完整接收数据的三种方法

    最近在使用python进行网络编程开发一个通用的tcpclient测试小工具.在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题.这 ...

  8. [Windows Server 2008] 安装SQL SERVER 2008

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装SQL S ...

  9. day2笔记

    今日内容: 1.常用数据类型即数据方法 2.文件处理 3.函数 一 列表: 在[]内,可以存放多个任意类型的值,并以逗号隔开. 一般用于存放学生的爱好,课堂的周期等等 优先掌握的操作: 1.按索引取值 ...

  10. JAVA如何获得数据库的字段及字段类型

    Java获取数据库的表中各字段的字段名,代码如下: import java.sql.Connection;import java.sql.DriverManager;import java.sql.R ...