【转】C++类中对同类对象private成员访问
私有成员变量的概念,在脑海中的现象是,以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 = ;
CTest tt = ;
// 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++的访问修饰符的作用是以类为单位,而不是以对象为单位。
通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问.
步骤是:通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据成员和成员函数(类的所有对象共用),而且还需要指明是哪个对象的数据成员(调用函数的对象自己的成员不用指明,因为有this指针;其他对象的数据成员可以通过引用或指针间接指明)
【转】C++类中对同类对象private成员访问的更多相关文章
- python---Django中模型类中Meta元对象了解
Django中模型类中Meta元对象了解 1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境) python manage.py shell ...
- 编写Java程序,实现对兵营类的封装,将兵营类中的所有属性设置为私有访问权限,方法设置为公有访问权限
返回本章节 返回作业目录 需求说明: 实现对兵营类的封装 将兵营类中的所有属性设置为私有访问权限. 将兵营类中所有属性的赋值方法设置为公有访问权限. 要求兵营名称的长度在4-8位之间. 要求兵营士兵的 ...
- c++类 用冒号初始化对象(成员初始化列表)
c++类 用冒号初始化对象(成员初始化列表) 成员初始化的顺序不同于它们在构造函数初始化列表中的顺序,而与它们在类定义中的顺序相同 #include<iostream> ; using n ...
- Effective C++ 条款15、16 在资源管理类中提供对原始资源的访问||成对使用new 与 delete要采取相同形式
1.在资源管理类中提供对原始资源的访问 前几个条款很棒,它们是对抗资源泄露的壁垒,但很多APIs直接指向 资源,这个时候,我们需要直接访问原始资源. 这里,有两种方法解决上述问题,我们 ...
- 类中被final修饰的成员变量需要初始化
类中被final修饰的成员变量需要初始化,否则编译不通过,因为final修饰后不能再赋值,因此必须初始化.
- 在Action类中获得HttpServletResponse对象的四种方法
在struts1.xAction类的execute方法中,有四个参数,其中两个就是response和request.而在Struts2中,并没有任何参数,因此,就不能简单地从execute方法获得Ht ...
- Effective Objective-C 2.0 — 第10条:在既有类中使用关联对象存放自定义数据
可以通过“关联对象”机制来把两个对象连起来 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系” 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于 ...
- spring mvc在普通类中获取HttpServletRequest对象
如题,需要在web.xml中配置request监听,如下 <listener> <description>spring request监听器</description&g ...
- service手动实例化(new)导致类中的spring对象无法注入的问题解决
下面说的这个画横线的可能是错误的,因为我之前用controller继承父类的注解对象的时候成功了,所以可能这次的唯一原因就是 不该把本该从ioc容器中拿出的对象通过new的方式实例化,至于继承注解对象 ...
随机推荐
- JAVA-前台编码,后台解码
前台 var objValue =window.encodeURI(window.encodeURI(queryObj)); alert(objValue); 后台 String descStr = ...
- PAT-乙级-1045. 快速排序(25)
1045. 快速排序(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 著名的快速排序算法里有一个经典的划分 ...
- 关于hibernate中双向外键关联one-to-one的property-ref=的问题(转)
大家都知道hibernate中的one-to-one映射主要有两种策略,(1)一对一主键关联(单向和双向).(2)一对一外键映射(单项和双向).本文主要讲解一下,一对一外键映射中的双向问题,在此前先通 ...
- 深入浅出 ES6:ES6 与 Babel / Broccoli 的联用
深入浅出 ES6指的是添加在 ECMASript 标准第六版中的 JavaScript 编程语言的新特性,简称为 ES6. 虽然 ES6 刚刚到来,但是人们已经开始谈论 ES7 了,它未来的样子,以及 ...
- auto_ptr,shared_ptr 智能指针的使用
Q: 那个auto_ptr是什么东东啊?为什么没有auto_array?A: 哦,auto_ptr是一个很简单的资源封装类,是在<memory>头文件中定义的.它使用“资源分配即初始化”技 ...
- C++11新特性:自动类型推断和类型获取
声明:本文是在Alex Allain的文章http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-functi ...
- ***用php的strpos() 函数判断字符串中是否包含某字符串的方法
判断某字符串中是否包含某字符串的方法 if(strpos('www.idc-gz.com','idc-gz') !== false){ echo '包含'; }else{ echo '不包含'; } ...
- 【BZOJ 3190】 3190: [JLOI2013]赛车 (半平面交)
3190: [JLOI2013]赛车 Description 这里有一辆赛车比赛正在进行,赛场上一共有N辆车,分别称为个g1,g2--gn.赛道是一条无限长的直线.最初,gi位于距离起跑线前进ki的位 ...
- c++ 孟岩推荐 书籍
c++ primer 中文版本 是 教程+参考书 扛梁之作c++ 标准程序库 对于c++熟手来说更为快捷effective c++ 永远是初学者必读的,但是c++11标准后的第四版,还未发布c++ ...
- Android 使用SDcard进行文件的读取
平时我们需要在手机上面存储想音频,视频等等的大文件,以前学过使用File进行存储(使用File操作进行存储):由于考虑到手机本身的存储空间小,这时候我们需要把文件存储在SDcard中,今天自己也学习了 ...