色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

從技術(shù)實(shí)現(xiàn)的角度破壞封裝性直接訪問(wèn)私有變量

CPP開(kāi)發(fā)者 ? 來(lái)源:高性能架構(gòu)探索 ? 2023-02-15 09:31 ? 次閱讀

C++教材的前幾章就介紹了其特性,即:C++是一門面向?qū)ο笳Z(yǔ)言,具有封裝、繼承和多態(tài)三個(gè)特點(diǎn)。后來(lái),隨著編碼的增多以及工作經(jīng)驗(yàn)的積累,對(duì)個(gè)概念的理解越來(lái)越深。編碼習(xí)慣也嚴(yán)格按照相應(yīng)的規(guī)則,該封裝的時(shí)候進(jìn)行封裝,該繼承的時(shí)候進(jìn)行繼承,以使得編程思維從之前的面向過(guò)程逐步過(guò)渡到面向?qū)ο蟆?/p>

作為開(kāi)發(fā)人員,遵循編程規(guī)則本來(lái)就無(wú)可厚非,但是如果大家都遵循規(guī)則難免會(huì)有創(chuàng)新或者技術(shù)進(jìn)步。有時(shí)候,在做某件事或者看到某個(gè)實(shí)現(xiàn)方案的時(shí)候,想想為什么要這么做,有沒(méi)有更好的實(shí)現(xiàn)方案,這個(gè)編程或者做事習(xí)慣往往使得自己受益匪淺。

比如,我們都知道每個(gè)線程都有一個(gè)自己的棧,線程內(nèi)的局部變量出了作用域就會(huì)被釋放,那么有沒(méi)有可能跨線程從另外一個(gè)線程去訪問(wèn)該線程的局部變量呢?其實(shí),問(wèn)題不算難,我們只需要嘗試即可,但往往缺少的就是這種嘗試。對(duì)于C++三大特性中的封裝特性,如果直接訪問(wèn)私有變量,則編譯器會(huì)報(bào)錯(cuò),那么有沒(méi)有其它方式可以訪問(wèn)私有變量呢?

今天,不妨試著反其道而行,嘗試以其他方式破壞封裝性,直接訪問(wèn)私有變量。

從一段代碼說(shuō)起

代碼示例如下:

#include

classA{
public:
A()=default;
private:
intdata_=0;
};

intmain(){
Aa;
std::cout<

在gcc5.4下進(jìn)行編譯,不出所料,編譯失敗,報(bào)錯(cuò)如下:

test.cc:在函數(shù)‘intmain()’中:
test.cc:7:15:錯(cuò)誤:‘int A::data_’是私有的
intdata_=0;

從報(bào)錯(cuò)信息看,因?yàn)閐ata_成員變量是私有的,而通過(guò)對(duì)象訪問(wèn)私有成員變量是不被允許的,除了通過(guò)重新定義一個(gè)公共接口,在該接口內(nèi)對(duì)data_進(jìn)行訪問(wèn)外,但是這種方式并沒(méi)有實(shí)現(xiàn)本文的目的即破壞封裝性,那么有沒(méi)有其它方式呢?

第一次嘗試

c++標(biāo)準(zhǔn)中有這樣一段描述:

The usual access checking rules do not apply to non-dependent names used to specify template arguments of the simple-template-id of the partial specialization. [ Note:The template arguments may be private types or objects that would normally not be accessible. Dependent names cannot be checked when declaring the partial specialization, but will be checked when substituting into the partial specialization. — end note ]

也就是說(shuō)模板參數(shù)可以是某個(gè)類的私有類型,所以,我們可以借助此條標(biāo)準(zhǔn)繼續(xù)實(shí)現(xiàn)我們的目的,代碼如下:

#include

classA{
public:
A()=default;
private:
intdata_=0;
};

template
int&GetPrivateData(A&obj){
returnobj.*Member;
}

templateint&GetPrivateData<&A::data_>(A&);

intmain(){
Aobj;
GetPrivateData<&A::data>(obj);

return0;
}

在上述代碼中,定義了一個(gè)函數(shù)模板,其模板參數(shù)為int A::*Member,功能是返回類A中的成員變量,編譯后,報(bào)錯(cuò)如下:

test.cc:在函數(shù)‘intmain()’中:
test.cc:7:15:錯(cuò)誤:‘int A::data_’是私有的
intdata_=0;
^
test.cc:22:3:錯(cuò)誤:在此上下文中
GetPrivateData<&A::data_>(obj);

看來(lái)此方式還是行不通,只能另想它法。

第二次嘗試

在上面的提示中,顯示不能直接訪問(wèn)私有成員,標(biāo)準(zhǔn)提供了個(gè)方法,就是將需要訪問(wèn)類私有成員的函數(shù)或者類聲明為friend。看到這塊,你可能會(huì)想,有了friend用得著你教?。

很快寫出如下這種代碼:

classA{
public:
A()=default;
private:
intdata_=0;

friendintAccess(constA&a){
returna.data_;
}
};

intmain(){
Aa;
Access(a);

return0;
}

無(wú)疑,上面這種代碼可以訪問(wèn)私有成員,但缺點(diǎn)是需要更改類實(shí)現(xiàn),下面將介紹一種方式,其在不修改類本身定義的情況下實(shí)現(xiàn)訪問(wèn)私有成員變量。

本著大方向不變的原則,依然使用模板的方式訪問(wèn)私有成員,而對(duì)于上節(jié)中提示的非法訪問(wèn)私有成員,我也采用將對(duì)應(yīng)函數(shù)聲明為friend的方式。

#include

classA{
public:
A()=default;
private:
intdata_=0;
};

template
classAccess{
public:
friendintGetPrivateData(A&obj){
returnobj.*Member;
}
};

templateclassAccess<&A::data_>;

intGetPrivateData(A&);


intmain(){
Aobj;
GetPrivateData(obj);

return0;
}

編譯 & 運(yùn)行,OK!!!

另辟蹊徑

在上一節(jié)實(shí)現(xiàn)中,使用了friend進(jìn)行訪問(wèn)控制,所以在考慮有沒(méi)有不使用friend的方式,于是在網(wǎng)上進(jìn)行搜索查閱,如下:

classA{
public:
A(intnum):data_(num){};
private:
intdata_=0;
};

template
classAccess{
public:
inlinestaticPtrTypeptr;
};

template
structPtrTaker{
structTransferer{
Transferer(){
Access::ptr=T;
}
};
inlinestaticTransferertr;
};

templateclassPtrTaker<&A::data_>;//顯示實(shí)例化

intmain(){
Aa{10};

intb=a.*Access::ptr;

return0;
}

說(shuō)真的,看到這種實(shí)現(xiàn)方式的時(shí)候,一臉懵逼,尤其是對(duì)模板用的不多的情況下,閱讀這短短幾十行代碼用了一天時(shí)間,其間也跟@Chunel駿哥哥一起討論,奈何太挫了,只能硬著頭皮自己研究,也跟群里的大佬們一起討論了下,再結(jié)合自己的理解,分析下這塊:

1、因?yàn)橛玫搅薸nline 變量以及模板參數(shù)為auto,所以上述代碼在cpp17上才可以運(yùn)行。

2、以&A::data_作為模板參數(shù),對(duì)類模板PtrTaker進(jìn)行顯示實(shí)例化,在顯示實(shí)例化的時(shí)候,雖然不創(chuàng)建對(duì)象,但是對(duì)于其中存在的靜態(tài)變量依然會(huì)進(jìn)行初始化。因此會(huì)調(diào)用Transferer類的構(gòu)造函數(shù),從而對(duì)Access::ptr進(jìn)行初始化

看上述代碼的時(shí)候,一開(kāi)始卡在了a.*Access::ptr這部分,后來(lái)經(jīng)過(guò)跟其他技術(shù)大佬進(jìn)行溝通,對(duì)這部分可以進(jìn)行拆分簡(jiǎn)化:

?p = Access::ptr;

?a.*p

看了下面的代碼示例,相信能便于理解:

classData{
public:
intnum_=0;
};

intmain(){
intData::*ptr=&Data::num_;

Datadata;
data.*ptr=10;

return0;
}

好了,我們接著進(jìn)行討論。

在使用對(duì)象訪問(wèn)成員的時(shí)候,其地址實(shí)際上分為兩部分的,以a.data_為例(此處忽略訪問(wèn)控制權(quán)限),一部分是a的this指針,另一部分是data_成員在A結(jié)構(gòu)里的偏移量,這個(gè)偏移量存儲(chǔ)在&A::data_中。在上面的代碼中,這個(gè)偏移量存儲(chǔ)在靜態(tài)數(shù)據(jù)ptr里了,即上面提到的Access::ptr。

所以,a.*p相當(dāng)于如下:

intA::*p=&A::data_;
intoffset=*(longlong*)&p;
intdata=*(int*)((char*)&a+offset);

好了,截止為此,通過(guò)模板方式訪問(wèn)類私有成員的討論結(jié)束了。

可能有人會(huì)有疑問(wèn),如果類有多個(gè)成員變量,又該如何訪問(wèn)呢,方式類似,代碼如下:

#include
#include

classA{
public:
A(intnum,std::stringv):data_(num),value_(v){};
private:
intdata_=0;
std::stringvalue_;
};

template
classAccess{
public:
inlinestatictypenameTag::typeptr;
};

template
structPtrTaker{
structTransferer{
Transferer(){
Access::ptr=V;
}
};
inlinestaticTransferertr;
};

structTag1{
usingtype=intA::*;
};

structTag2{
usingtype=std::stringA::*;
};

templateclassPtrTaker;//顯示實(shí)例化
templateclassPtrTaker;//顯示實(shí)例化

intmain(){
Aa{0,"abc"};

std::cout<::ptr;
}






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137398
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1642

    瀏覽量

    49229
  • C++語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    147

    瀏覽量

    7017
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3408

原文標(biāo)題:訪問(wèn)私有成員——從技術(shù)實(shí)現(xiàn)的角度破壞"封裝" 性

文章出處:【微信號(hào):CPP開(kāi)發(fā)者,微信公眾號(hào):CPP開(kāi)發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于CXL的直接訪問(wèn)高性能內(nèi)存分解框架

    鑒于KAIST的HPC根源,將DirectCXL原型放在一起的研究人員專注于使用遠(yuǎn)程直接內(nèi)存訪問(wèn)(RDMA)協(xié)議將CXL內(nèi)存池與跨系統(tǒng)直接內(nèi)存訪問(wèn)進(jìn)行比較。
    發(fā)表于 09-23 10:50 ?1392次閱讀

    CysecureTools如何直接訪問(wèn)外部存儲(chǔ)設(shè)備內(nèi)的密鑰呢?

    顯然不符合安全標(biāo)準(zhǔn)。 那么,如標(biāo)題所示,CysecureTools應(yīng)該如何直接訪問(wèn)外部存儲(chǔ)設(shè)備內(nèi)的密鑰呢?\"
    發(fā)表于 01-31 08:08

    Labview通過(guò)VXI總線直接訪問(wèn)測(cè)量?jī)x器內(nèi)部寄存器

    VXI總線直接訪問(wèn)測(cè)量?jī)x器內(nèi)部寄存器,從而在線獲取干涉儀的距離測(cè)量結(jié)果,從而與我的位移測(cè)量系統(tǒng)作比對(duì)。大家如果對(duì)激光干涉儀不了解不要緊,請(qǐng)告訴我如何通過(guò)VXI總線直接訪問(wèn)測(cè)量?jī)x器內(nèi)部寄存器,有遇上類似情況的嗎? 本人對(duì)VXI及Labview了解不多,望有人能討論和幫忙。不
    發(fā)表于 05-07 16:30

    1831B直接訪問(wèn)垂直操作說(shuō)明

    1831B直接訪問(wèn)垂直操作說(shuō)明
    發(fā)表于 10-26 11:52

    python私有變量私有方法

    下劃線前導(dǎo)的方法,可以使用 實(shí)例._類名__方法名() 進(jìn)行訪問(wèn)私有變量私有方法,雖然有辦法訪問(wèn),但是仍然不建議使用上面給出的方法
    發(fā)表于 03-08 16:30

    UCOS擴(kuò)展例程-UCOSIII直接訪問(wèn)共享資源區(qū)

    UCOS擴(kuò)展例程-UCOSIII直接訪問(wèn)共享資源區(qū)
    發(fā)表于 12-14 17:24 ?20次下載

    匯編代碼訪問(wèn)C全局變量

    12.2 匯編代碼訪問(wèn) C target=_blank style=cursor:pointer;color:#D05C38;text-decoration:underline;》C 全局變量
    發(fā)表于 10-19 09:25 ?0次下載

    Python私有變量的定義方法

    在類內(nèi)部使用,不被外部調(diào)用,且當(dāng)變量被標(biāo)記為私有后,調(diào)用時(shí)需再變量的前端插入類名,在類名前添加一個(gè)下劃線,即“_ClassName__變量名”形式。Python
    發(fā)表于 02-13 16:49 ?1684次閱讀

    smarty如何調(diào)用PHP常量

    保留變量不需要從PHP腳本中分配,是可以在模板中直接訪問(wèn)的數(shù)組類型變量,通常被用于訪問(wèn)一些特殊的模板變量。例如,
    發(fā)表于 03-20 15:24 ?3次下載
    smarty如何調(diào)用PHP常量

    C++中類的繼承訪問(wèn)級(jí)別學(xué)習(xí)總結(jié)(二)

    上一篇文章我們介紹了c++中類的繼承學(xué)習(xí)總結(jié);今天我們繼續(xù)來(lái)分享c++中類的繼承中的訪問(wèn)級(jí)別的學(xué)習(xí)總結(jié)。一、繼承中的訪問(wèn)級(jí)別學(xué)習(xí):1、子類是否可以直接訪問(wèn)父類的私用成員嗎?面向?qū)ο罄?/div>
    的頭像 發(fā)表于 12-24 16:10 ?771次閱讀

    python私有變量私有方法

    python私有變量私有方法 1. 下劃線妙用 在 Python 中,下劃線可是非常推薦使用的符號(hào): 變量名推薦使用下劃線分隔的蛇形命名法 魔法方法、構(gòu)造函數(shù)都需要使用雙下劃線 對(duì)于
    的頭像 發(fā)表于 03-08 16:30 ?2042次閱讀

    如何實(shí)現(xiàn)SIMATIC HMI對(duì)驅(qū)動(dòng)參數(shù)的直接訪問(wèn)

    SINAMICS V90PN驅(qū)動(dòng)器可以通過(guò)模擬S7-CPU,將數(shù)據(jù)庫(kù)訪問(wèn)HMI映射到驅(qū)動(dòng)參數(shù),該功能可實(shí)現(xiàn)在沒(méi)有SIMATIC S7控制器時(shí),SIMATIC HMI對(duì)驅(qū)動(dòng)參數(shù)的直接訪問(wèn)
    的頭像 發(fā)表于 08-10 17:59 ?2050次閱讀
    如何<b class='flag-5'>實(shí)現(xiàn)</b>SIMATIC HMI對(duì)驅(qū)動(dòng)參數(shù)的<b class='flag-5'>直接訪問(wèn)</b>呢

    InfiniBand和遠(yuǎn)程直接訪問(wèn)是什么,如何進(jìn)行配置

    本文簡(jiǎn)單描述了InfiniBand 和遠(yuǎn)程直接訪問(wèn)(RDMA)是什么,以及在實(shí)踐中如何配置InfiniBand網(wǎng)絡(luò)硬件。另外,本文檔解釋了如何配置與 InfiniBand 相關(guān)的服務(wù)。
    的頭像 發(fā)表于 11-25 14:26 ?1732次閱讀

    實(shí)現(xiàn)HMI直接訪問(wèn)驅(qū)動(dòng)參數(shù)的方法

    SINAMICS V90PN驅(qū)動(dòng)器可以通過(guò)模擬S7-CPU,將數(shù)據(jù)庫(kù)訪問(wèn)HMI映射到驅(qū)動(dòng)參數(shù),該功能可實(shí)現(xiàn)在沒(méi)有SIMATIC S7控制器時(shí),SIMATIC HMI對(duì)驅(qū)動(dòng)參數(shù)的直接訪問(wèn)
    的頭像 發(fā)表于 07-11 17:14 ?858次閱讀
    <b class='flag-5'>實(shí)現(xiàn)</b>HMI<b class='flag-5'>直接訪問(wèn)</b>驅(qū)動(dòng)參數(shù)的方法

    STM32L4直接訪問(wèn)內(nèi)存模塊(DMA)介紹

    電子發(fā)燒友網(wǎng)站提供《STM32L4直接訪問(wèn)內(nèi)存模塊(DMA)介紹.pdf》資料免費(fèi)下載
    發(fā)表于 08-01 10:15 ?1次下載
    STM32L4<b class='flag-5'>直接訪問(wèn)</b>內(nèi)存模塊(DMA)介紹
    主站蜘蛛池模板: 亚洲AV无码乱码国产麻豆P| 亚洲精品婷婷无码成人A片在线| 亚洲高清在线视频| 国产精品久久久久久久久99热 | 87.6在线收听| 久久久伊人影院| 张津瑜的9分58秒7段免费| 宝贝你骚死哥了好爽| 美女张开腿让男人桶爽无弹窗| 中文视频在线观看| 免费啪视频观试看视频| 99热成人精品国产免男男| 嫩草影院在线观看精品视频| 99在线这精品视频| 日本黄色www| 国产成人欧美日韩在线电影| 午夜DJ国产精华日本无码| 国产真实女人一级毛片| 婬香婬色天天视频| 末成年美女黄网站色大片连接| jizzjizz中国大学生| 色多多涩涩屋下载软件| 国产亚洲精品久久久久久久软件| 秋秋影视午夜福利高清| 伊人大香线蕉精品在线播放| 国产成人在线小视频| 学校捏奶揉下面污文h| 国产白丝精品爽爽久久蜜臀| 午夜在线观看免费完整直播网页| 国精产品砖一区二区三区糖心 | 日日摸夜夜嗷嗷叫日日拍| 国产精品久久精品| 亚洲一区免费看| 男人都懂www深夜免费网站| 高清国语自产拍在线| 亚洲日韩视频免费观看| 男生射女生| 国产精品系列在线观看| 中文字幕a有搜索网站| 日本久久中文字幕精品| 精品久久久久久无码人妻国产馆|