為啥不能#define private public了?
- 2019 年 11 月 6 日
- 筆記
今天在寫一個單元測試的時候出現了如下編譯錯誤:
以前用gtest為了測試業務程式碼里的private函數和變數,一直是在單元測試程式碼通過#define private public這樣的trick達到測試業務程式碼的private變數的目的.怎麼現在就不行了呢?
現在用的gcc版本是8.3 以前用的gcc4.8肯定是沒問題的.
剛看到這個編譯告警我是很懵逼的,我沒有使用sstream這個頭文件啊,而且這個redclared是什麼鬼,我沒有定義過這個struct __xfer_bufptrs啊,怎麼會有重定義的問題呢.
根據編譯錯誤告警sstream:redclared with diffrent access,我們打開標準庫的sstream看一下.
在第67行,聲明了__xfer_bufptrs,但是並沒有顯式的聲明訪問許可權,那默認的就是private.
302行,在具體的定義處,確又顯式地聲明了訪問許可權為private.
原來是我的測試程式碼引用了一個第三方的頭文件,第三方的頭文件里用到了標準庫的sstream. 當我們單元測試程式碼里去#define private public時,對sstream第67行是無效的,這裡__xfer_bufptrs被認為是private,而到了第302行,private被替換為public,_xfer_bufptrs被認為是public. 這就造成了編譯的錯誤:訪問許可權的重定義衝突了.
這個事情告訴我們,自己寫的業務程式碼變數許可權也最好要顯式地聲明清楚.不然你就沒法在單元測試里用#define private public這種trick啦.
沒辦法,為了測試業務程式碼里的private變數,只好修改待測試的業務程式碼
#ifdef UNIT_TEST #define MYPRIVATE public #else #define MYPRIVATE private #endif class yourclassname { //private: MYPRIVATE: int a; }
然後在單元測試程式碼里#define UNIT_TEST.
或者你覺得這種方式看起來很ugly的話,只能添加public介面去獲取private變數了,但是當你要測試的private變數很多時,也是個很麻煩的事情.