[C++参考]私有成员变量的理解
私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量.
然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了私有成员变量,因而,产生了困惑.下面以具体实例进行说明:
疑惑:为什么第26行和第32行代码可以编译通过,而第39行和第40行代码会产生编译错误?
class CTest {
public:
CTest(int i);
CTest(const CTest& rhs);
CTest& operator=(const CTest& rhs);
void printCTest(const CTest& rhs);
private:
int value;
};
CTest::CTest(int i):value(i)
{
cout<<"Contructor of CTest"<<endl;
}
CTest::CTest(const CTest& rhs):value(rhs.value)
{
cout<<"Copy contructor of CTest"<<endl;
}
CTest& CTest::operator=(const CTest& rhs)
{
cout<<"Assign function of CTest"<<endl;
if(this == &rhs)
return *this;
value = rhs.value; //通过对象访问私有成员变量
return *this;
}
void CTest::printCTest(const CTest& rhs)
{
cout<<rhs.value<<endl; //通过对象访问私有成员变量
}
int main()
{
CTest t = 1;
CTest tt = 2;
// cout<<t.value<<endl; //通过对象访问私有成员变量,编译错误
// cout<<tt.value<<endl; //通过对象访问私有成员变量,编译错误
t.printCTest(tt);
}
产生这种疑惑的原因是自己对私有成员变量的理解有误,封装是编译期的概念,是针对类型而非对象的,在类的成员函数中可以访问同类型实例对象的私有成员变量.
具体的解析如下:从变量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++参考]私有成员变量的理解的更多相关文章
- c++中嵌套类,外部类访问内部类的私有成员变量
在嵌套类中,内部类可以直接访问外部类的私有成员变量,但是外部类不能直接访问内部类的私有成员变量,必须把外部类声明为内部类的友元类 /********************************** ...
- 『无为则无心』Python面向对象 — 51、私有成员变量(类中数据的封装)
目录 1.私有成员变量介绍 (1)私有成员变量概念 (2)私有成员变量特点 (3)私有成员变量体验 2.属性私有化工作原理 3.定义成员变量的标识符规范 4.私有成员变量的获取和设置方式 1.私有成员 ...
- Java子类访问父类的私有成员变量
/**子类会继承父类所有的属性和方法. * 但是根据不同的权限标识符,子类不可见父类的私有变量,但可以通过父类的公共方法访问私有变量 * 所以对于重名变量,子类和父类都各有一份. * 对于子类和父类中 ...
- Extension 代表的是私有成员变量
不明白就问百度.百度搜索得到的结果总是那么多却总是那么千篇一律.不晓得是什么原因. 刚完成一个项目.需要整理一下知识点. 在新项目开始的时候就比较矛盾.因为以前的项目中都有BaseViewContro ...
- java 反射获取设置私有成员变量的值
for (Object arg:args) { //处理applicationCode Class<?> argClass = arg.getClass(); Field applicat ...
- private成员变量真的私有吗?(用指针刨他祖坟)
今天写程序时突然想到的,为什么不用指针去获取类的成员变量呢.于是做了这个实验.首先定义了一个类: class Test { private: int i; char c; int* p; public ...
- 继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类。 (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。 (3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。 (4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。 分析以上程
继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法.(3)子类中定义的成员变量和父类中定义的 ...
- java基础疑难点总结之成员变量的继承,方法重载与重写的区别,多态与动态绑定
1.成员变量的继承 1.1要点 子类用extends关键字继承父类.子类中可以提供新的方法覆盖父类中的方法.子类中的方法不能直接访问父类中的私有域,子类可以用super关键字调用父类中的方法.在子类中 ...
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一. 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...
随机推荐
- kafka初探
http://www.infoq.com/cn/articles/kafka-analysis-part-1
- linux c in common use function reference manual
End User License Agreement guarantees or warranties,大战前得磨刀!!!!! Tips:C Funcs Chk header Modules!
- Michael Kors成了时尚行业的公敌-股票频道-和讯网
Michael Kors成了时尚行业的公敌-股票频道-和讯网 Michael Kors成了时尚行业的公敌 字号 评论 邮件 纠错 2014年03月03日17:32 来源:财经天下 全球消费不 ...
- hdu 1394 zoj 1484 求旋转序列的逆序数(并归排序)
题意:给出一序列,你可以循环移动它(就是把后面的一段移动到前面),问可以移动的并产生的最小逆序数. 求逆序可以用并归排序,复杂度为O(nlogn),但是如果每移动一次就求一次的话肯定会超时,网上题解都 ...
- HDU 1976 prime path
题意:给你2个数n m.从n变成m最少须要改变多少次. 当中: 1.n m 都是4位数 2.每次仅仅能改变n的一个位数(个位.十位.百位.千位),且每次改变后后的新数为素数 思路:搜索的变形题,这 ...
- android raw与assets资源
*res/raw和assets的同样点: 1.两者文件夹下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制. *res/raw和assets的不同点: 1.res/raw中的文件会被映射 ...
- malloc/free和new/delete的区别汇总
一.基本概念 malloc/free 1.函数原型及说明: void* malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败,则返回 ...
- 八皇后问题-回溯法(MATLAB)
原创文章,转载请注明:八皇后问题-回溯法(MATLAB) By Lucio.Yang 1.问题描述 八皇后问题是十九世纪著名数学家高斯于1850年提出的.问题是:在8*8的棋盘上摆放8个皇后,使其不能 ...
- 03-C语言编码规范和变量
目录: 一.C语言的编码规范 二.变量 三.浮点型float 四.变量名命名规则 五.变量作用域与生命周期 回到顶部 一.C语言的编程规范 1 语句可以分开放在任意位置 2 空格可以让代码更清晰 3 ...
- IOS 特定于设备的开发:Info.plist属性列表的设置
应用程序的Info.plist属性列表使你能够在向iTunes提交应用程序时指定应用程序的要求.这些限制允许告诉iTunes应用程序需要哪些设备特性. 每个IOS单元都会提供一个独特的特性集.一些设备 ...