【转】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 = 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++的访问修饰符的作用是以类为单位,而不是以对象为单位。
  通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问.
  步骤是:通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据成员和成员函数(类的所有对象共用),而且还需要指明是哪个对象的数据成员(调用函数的对象自己的成员不用指明,因为有this指针;其他对象的数据成员可以通过引用或指针间接指明)

转载于:https://www.cnblogs.com/yanqi0124/p/3828507.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 导出命令

mysqldump --no-defaults -u root -p dbname > c:\www\test.sql windows 下使用。转载于:https://www.cnblogs.com/chenshuo/p/4646070.html

ubuntu16.04编译boost for Android(boost 1.65)

下载boost源码 在官网下载指定版本的源码 http://www.boost.org/users/history/ 编译boost源码 1.进入源码目录执行./bootstrap.sh生成编译工具 2.编辑project-config.jam文件,替换如下内容 # define platform name of ndk import os ; if [ os.name ] CYGWIN || [ os.na…

Jquery获取select,dropdownlist,checkbox下拉列表框的值

jQuery获取 Select选择的Text和Value:语法解释&#xff1a;1. $("#select_id").change(function(){//code...}); //为Select添加事件&#xff0c;当选择其中一项 时触发2. var checkText$("#select_id").find("option:selected").text(); //获…

maven2 + tomcat6 + eclipse集成配置

转载&#xff1a;http://wenku.baidu.com/view/d64147c676eeaeaad1f330d4.html?review /*maven2 tomcat6 eclipse集成配置maven的配置环境变量M2_HOME maven主目录环境变量path maven主目录/binapache-maven/conf/setting.xml文件1、新建maven本地仓库文件夹apache-maven2…

定位pure virtual method called问题

我是在进行boost test的时候遇到了这样的一个问题&#xff0c;最后问题定位到测试用例中&#xff0c;测试的工程以及单元测试的代码是之前的&#xff0c;没有开发完&#xff0c;我实习的时候leader让我完善一下测试框架&#xff0c;添加一下测试代码。 目标机是Android&#x…

环形矩阵

1.逆时针 代码&#xff1a; 1 // huanxingjz.cpp : Defines the entry point for the console application.2 //3 4 #include "stdafx.h"5 #include <stdio.h>6 #include <iostream>7 #include "windows.h"8 #define MAX 409 using namespace …

检查MySQL主从数据一致性

未公布转载于:https://www.cnblogs.com/cuizhipeng/p/4646489.html

统计文件里有多少个字符(only a simple cpp)

通过重定向读取文件内容&#xff0c;并检测其中有多少字符&#xff0c;包括空格&#xff0c;但tap键可能统计结果不同。 #include<iostream>int main(int argc,char *argv[]){using std::cin,std::cout,std::endl;cout<<"Usage:"<<argv[0]<<…

Winsock网络编程笔记(4)----基本的理论知识

前面的笔记记录了Winsock的入门编程&#xff0c;领略了Winsock编程的乐趣。。但这并不能算是掌握了Winsock&#xff0c;加深理论知识的理解才会让后续学习更加得心应手。。因此&#xff0c;这篇笔记将记录一些有关Winsock的基本理论知识&#xff0c;由于是一篇笔记&#xff0c;…

30分钟学会使用grunt打包前端代码

http://www.cnblogs.com/yexiaochai/p/3603389.html转载于:https://www.cnblogs.com/wuxiang/p/4647280.html

简单shell:删除五日之前的日志文件

曾经在某公司面试的时候被问到了类似的问题。 假设在logs文件夹存放了许多日志文件 比如&#xff1a;20190204.log、20190205.log、20190206.log。。。 我们要删除特定日期之前的日志 在这里展示的是使用shell指令中的find指令完成操作 首先看一下find指令的命令格式&#xf…

Method Swizzle黑魔法,修改 ios 系统类库方法(转载)

一般来说&#xff0c;系统提供的方法已经足够开发了&#xff0c;但是有的时候有些需求用普通方法不好做。 如&#xff1a;在所有的viewcontroll 的viewwillappear&#xff1a;方法之前打个log 你可能会这么做&#xff1a; 1. 建一个uiviewcontroll 父类&#xff0c;重写viewwil…

win10无法开启夜间模式

在学校的时候没感觉&#xff0c;一进公司发现电脑还是需要设置一下护眼的&#xff0c;但是在设置的时候却遇到夜间模式无法开启的问题。 首先在左下角搜索设备管理器 找到显示适配器 查看显示器设备状态 如果设备图标上有黄三角感叹号则说明该设备驱动有问题&#xff0c;需要…

Linux LVM学习总结——扩展卷组VG

Linux服务器由于应用变更或需求的缘故&#xff0c;有可能出现分区空间不足的情况&#xff0c;此时往往需要进行扩容&#xff08;要增加分区的空间&#xff09;&#xff0c;而采用LVM的好处就是可以在不需停机的情况下可以方便地调整各个分区大小。如下所示&#xff0c;分区/u05…

【液晶模块系列基础视频】1.3.iM_TFT30模块简介

【液晶模块系列基础视频】1.3.iM_TFT30模块介绍 技术论坛&#xff1a;http://www.eeschool.org 博客地址&#xff1a;http://xiaomagee.cnblogs.com 官方网店&#xff1a;http://i-board.taobao.com 银杏科技 GINGKO TECH. 保留权利&#xff0c;转载请注明出处 本次教学视频介…

C++控制向文件中写入浮点数的格式

有时会遇到向文件中写入一定格式的浮点数&#xff0c;为了对齐美观&#xff0c;常常采用控制小数点后的位数并用0补齐缺少的位数的方法。 #include <iostream> #include <iomanip> #include <fstream> using namespace std;int main(){double pi3.14;ofstre…

项目管理工具到底应该为谁服务?

项目管理工具到底应该为谁服务&#xff1f;为管理者&#xff0c;还是为了团队&#xff1b;为了管理报表&#xff0c;还是为了协作需求&#xff0c;这些是在项目管理工具选择或开发时需要面对和思考的一个问题。 传统项目管理工具在团队内部臭名昭著 项目管理工具当初都是为了项…

二叉树的递归定义及存储

定义 最多有两棵子树的有序树&#xff0c;称为二叉树。二叉树是一种特殊的树。 递归定义&#xff1a;二叉树是n(n>0)个有限结点构成的集合。N0称为空二叉树&#xff1b;n>0的二叉树由一个根结点和两互不相交的&#xff0c;分别称为左子树和右子树的二叉树构成。 二叉树中…

C++统计微妙级时间消耗(chrono)

有时我们需要统计某段程序运行所消耗的时间&#xff0c;通过C的chrono库&#xff0c;我们可以轻松实现这一需求&#xff0c;例如&#xff0c;我们求斐波那契数列消耗的时间。 #include <iostream> #include <chrono> #include <iomanip> using namespace st…