【轉】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.pswp.cn/news/375743.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375743.shtml
英文地址,請注明出處:http://en.pswp.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…