C++ 私有成员变量的理解
私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量.
然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了私有成员变量,因而,产生了困惑.下面以具体实例进行说明:
疑惑:为什么第26行和第32行代码可以编译通过,而第39行和第40行代码会产生编译错误?
![](/assets/blank.gif)
1 class CTest { 2 public: 3 CTest(int i); 4 CTest(const CTest& rhs); 5 CTest& operator=(const CTest& rhs); 6 void printCTest(const CTest& rhs); 7 private: 8 int value; 9 }; 10 11 CTest::CTest(int i):value(i) 12 { 13 cout<<"Contructor of CTest"<<endl; 14 } 15 16 CTest::CTest(const CTest& rhs):value(rhs.value) 17 { 18 cout<<"Copy contructor of CTest"<<endl; 19 } 20 21 CTest& CTest::operator=(const CTest& rhs) 22 { 23 cout<<"Assign function of CTest"<<endl; 24 if(this == &rhs) 25 return *this; 26 value = rhs.value; //通过对象访问私有成员变量 27 return *this; 28 } 29 30 void CTest::printCTest(const CTest& rhs) 31 { 32 cout<<rhs.value<<endl; //通过对象访问私有成员变量 33 } 34 35 int main() 36 { 37 CTest t = 1; 38 CTest tt = 2; 39 // cout<<t.value<<endl; //通过对象访问私有成员变量,编译错误 40 // cout<<tt.value<<endl; //通过对象访问私有成员变量,编译错误 41 t.printCTest(tt); 42 }
![](/assets/blank.gif)
产生这种疑惑的原因是自己对私有成员变量的理解有误,封装是编译期的概念,是针对类型而非对象的,在类的成员函数中可以访问同类型实例对象的私有成员变量.
具体的解析如下:从变量value的符号是怎么解析的分析.
1.确定符号的查找域
如第26行代码,当编译器发现value变量时,它会在value变量所属的对象rhs的类域中寻找该符号.
2.确定当前域中哪些符号可以访问
由第1步可知,当前查找的域是类域,而printCTest函数在CTest类体中,所以printCTest可以访问CTest类中的所有变量(包括私有成员变量),因而value符号在CTest类域中被找到.
如第39行代码,main函数不在CTest类体中,所以main函数不可以访问CTest类域中的私有成员变量.
3.符号已查找到,编译通过
类成员变量的访问权限是编译器强加的,编译器可以找到value,通过编译,自然就可以访问到value变量的值.
直觉上,我们会以为第26行代码中value符号的查找域应该是对象rhs对应的作用域,然而C++编译器的实现却是在对象rhs的类域查找value符号.
启发:有些直觉是靠不住的,需要深入分析其背后的实现原理,才可以理解透彻.
C++ 私有成员变量的理解相关推荐
- 私有成员变量理解的补充
在设计和实现当前类时,实现拷贝构造函数和赋值构造函数时,甚至在成员函数的内部是可以直接访问当前类的对象(以参数的形式)的私有成员变量的.考虑如下的代码: class Test { public:Tes ...
- java 反射私有变量赋值_通过反射,操作私有成员变量(取/赋值),调用私有方法...
Java的反射工具很强大,有句著名的话:No reflection ,no frameworks. 工作中直到涉及到UT,才体会到它的重要性,现归纳整理一个小例子: 反射工具类:import java ...
- 封装之--通过类中公有方法访问私有成员变量
如何在ClassB中访问ClassA的私有成员变量?(典型的封装案例) 通过在ClassA中定义公有的成员方法,然后,在ClassB中通过ClassA的对象调用ClassA中的公有方法,来访问Clas ...
- java 私有成员方法_Java Reflection 教程(7):类私有成员变量和方法
一般来说,不可以访问类的私有成员变量和调用类的私有方法.但通过Java Reflection API可以绕过这个限制,前面使用的getMethods, getFields,getConstructor ...
- 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)
访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...
- C++57个入门知识点_17 类的访问权限及C语言模拟类的封装(类的私有权限突破方法:编译期进行权限检查,运行期通过指针修改类的私有成员变量;利用函数指针对结构体中成员变量进行修改;CPU大小尾排列)
接上篇:C++57个入门知识点_16 类的标准写法(类名.成员变量.成员函数及对象命名规则:成员变量一般为私有,成员函数为公有并暴露给外部使用成员变量:防止类过大,声明写在.h,实现写在.cpp,调用 ...
- 设计复数类 Complex继承于数字类 Number,私有成员变量包括 double类型的实部rea(父类 Number中已定义)和虚部imag,公有成员方法包括两个构造方法(一个不带参数的和一个带两
设计复数类 Complex继承于数字类 Number,私有成员变量包括 double类型的实部rea(父类 Number中已定义)和虚部imag,公有成员方法包括两个构造方法(一个不带参数的和一个 ...
- 在python语言中定义私有成员变量的方法是_Python在类中有“私有”变量吗?
回答(11) 2 years ago python中的私有变量或多或少是一个hack:解释器故意重命名变量 . class A: def __init__(self): self.__var = 12 ...
- java 单元测试 私有成员变量,单元测试时测试一个private私有方法 - - ITeye博客
直接上例子 待测试的类 [code="java"]public class Calculator { private int count = 0; private int add( ...
最新文章
- 【Python】ubuntu14安装pycaffe环境:python2.7及依赖库
- 90%人工智能公司都亏损?AI盈利难背后的大数据门槛
- Django之url和视图函数
- 可视化工具第一篇(百度Echarts)
- 大牛带你学优化~案例进阶Mysql优化
- 只读变量(常量)和位置变量
- 【Java】文件锁定与系列NIO操作
- ActiveMQ消息队列的使用
- ssh登录到esxi机器中后开关虚拟机
- pandas小记:pandas数据结构和基本操作
- 【2012百度之星/初赛上】小小度刷礼品
- Ubuntu编写第一个Python程序
- 软件工程 超市库存管理系统 设计报告
- 嵌入式入门必去的网站 —— 介绍的非常详细
- 视觉工程师:工业相机50问
- solaris 命令大全
- vm虚拟机开启蓝屏问题
- 威联通(NAS)搭建个人音乐中心
- 用matlab绘制P三曲线,科学网—水文频率曲线及MATLAB绘制 - 张凌的博文
- 用Ps制作网页展示总结
热门文章
- java实现二分查找-两种方式
- Activemq实战
- Nginx教程-安装
- 创建用户赋权限_MySQL实战第84篇:MySQL数据库添加用户和赋权限,在8.0版本!
- arcgis加载天地图_ArcGIS Runtime SDK for Android100.5.0端加载天地图服务
- 学习oop知识之OOP的封装
- 试题 G: 外卖店优先级 第十届蓝桥杯
- Just for fun——go实现一下观察者模式
- 查看mysql进程--show processlist
- PHP 杂谈《重构-改善既有代码的设计》之二 对象之间搬移特性