c++命名對象和匿名對象的解析
最近在看muduo庫,對裡面的日志庫比較感興趣,於是看到瞭以下的語句:
剛看到這些語句時,和平時遇到日志打印的語句不太一樣,很疑惑這樣一條語句是怎麼把日志打印出來的。網上搜索一翻後,學到瞭一個知識點:匿名對象。其實在平時的編碼中我們也經常會遇到匿名對象,隻是沒有關註。簡單的一個匿名對象如:
std::string anonymous = std::string(“anonymous”);
像按值傳遞的對象(函數入參,函數返回值)都是匿名對象,那匿名對象的特點是什麼呢?通過下面一段代碼可知:
#ifndef __CLOGER_H__ #define __CLOGER_H__ #include <string> #include <stdlib.h> #include <stdio.h> class CLoger { public: explicit CLoger(std::string &str): mStr(str) { } ~CLoger() { printf("destructor mStr = %s\n", mStr.c_str()); } std::string &string() { return mStr; } private: std::string mStr; }; #endif #include "anonymous_object.h" int main() { std::string name("name"); CLoger loger(name); //具名對象,main函數退出後才會銷毀 std::string anonymous("anonymous"); CLoger(anonymous).string(); //匿名對象,使用完即銷毀,即此語句結束後立即調用其析構函數 printf("main finish!\n"); return 0; }
運行結果如下:
1,命名對象(非new)在離開作用域後,調用析構函數。
2,匿名對象在離開定義它的語句後,調用析構函數。
瞭解匿名對象的特點後,回到上面的日志打印語句,如其中一條語句:
#define LOG_TRACE if (CLogger::logLevel() <= CLogger::TRACE) \
CLogger(__FILE__, __LINE__, CLogger::TRACE, __func__).stream()
定義瞭一個匿名對象CLogger,在調用完這條語句後,調用其析構函數:
CLogger::~CLogger() { mImpl.finish(); //打印結尾添加文件名和行號 const CLogStream::Buffer& buf(stream().buffer()); g_output(buf.data(), buf.length()); //函數指針調用,默認是輸出到標準輸出stdout,這裡是日志最終輸出的語句 if (mImpl.mLevel == FATAL) { g_flush(); abort(); } }
所以,隻要調用語句如LOG_INFO:
int main(int argc, char* argv[]) { char name[256]; strncpy(name, argv[0], 256); CAsyncLogging log(::basename(name), kRollSize); log.start(); g_asyncLog = &log; bool longLog = argc > 1; // bench(longLog); LOG_INFO << "loggingTest!"; return 0; }
這個日志庫已經被我抽離出來,可以單獨編譯一個日志庫,有興趣的同學可以到git下載。
到此這篇關於c++命名對象和匿名對象的解析的文章就介紹到這瞭,更多相關c++命名對象和匿名對象內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!