Location類提供了一個(gè)對(duì)象構(gòu)建時(shí)所在位置的基礎(chǔ)信息,是chromium項(xiàng)目中的https://code.google.com/p/chromium/codesearch#chromium/src/base/location.h精簡(jiǎn)版本。在WebRTC項(xiàng)目中位于rtc_base/location.h和rtc_base/location.cc中。
class Location {
public:
// Constructor should be called with a long-lived char*, such as __FILE__.
// It assumes the provided value will persist as a global constant, and it
// will not make a copy of it.
//
// TODO(deadbeef): Tracing is currently limited to 2 arguments, which is
// why the file name and line number are combined into one argument.
//
// Once TracingV2 is available, separate the file name and line number.
Location(const char* function_name, const char* file_and_line);
Location();
Location(const Location& other);
Location& operator=(const Location& other);
const char* function_name() const { return function_name_; }
const char* file_and_line() const { return file_and_line_; }
std::string ToString() const;
private:
const char* function_name_;
const char* file_and_line_;
};
// Define a macro to record the current source location.
#define RTC_FROM_HERE RTC_FROM_HERE_WITH_FUNCTION(__FUNCTION__)
#define RTC_FROM_HERE_WITH_FUNCTION(function_name) \
::rtc::Location(function_name, __FILE__ ":" STRINGIZE(__LINE__))
}
該類簡(jiǎn)單易懂,但是簡(jiǎn)單之中也存在一些值得注意之處:
- 由Location的兩個(gè)成員function_name_與file_and_line_可知,Location存儲(chǔ)著對(duì)象在哪個(gè)函數(shù)中產(chǎn)生,對(duì)象在哪個(gè)文件的哪一行代碼中產(chǎn)生的信息。
- 雖然Location提供了4個(gè)構(gòu)造函數(shù),實(shí)際使用上并不會(huì)直接使用構(gòu)造方法去創(chuàng)建Location對(duì)象,而是使用宏RTC_FROM_HERE。如果將該宏展開,會(huì)發(fā)現(xiàn)其等效于:Location( __FUNCTION __, __FILE __ ":" #( __LINE __)),其中 __FUNCTION __,__FILE __,__LINE __是C++編譯器的內(nèi)置宏定義,分別輸出代碼所在的函數(shù)名,文件名以及行號(hào)。
- 上述宏相當(dāng)于調(diào)用Location類的Location(const char* function_name, const char* file_and_line)構(gòu)造函數(shù),并傳入了由C++內(nèi)置宏靜態(tài)編譯時(shí)產(chǎn)生的字符串常量,這些常量都是long-lived char*,因此,上述構(gòu)造函數(shù)沒有對(duì)傳入的值重新分配空間來(lái)拷貝字符串,而是簡(jiǎn)單的記錄這些常量字符串的地址。同時(shí),Location也沒有提供析構(gòu)函數(shù)來(lái)銷毀內(nèi)部function_name_以及file_and_line_所占用的空間,直到程序盡頭所占空間自然釋放。
- 同上述原因,Location的拷貝構(gòu)造與賦值構(gòu)造也不會(huì)為內(nèi)部的成員重新分配空間,沒有使用深拷貝。
Location類的源碼如下所示
Location::Location(const char* function_name, const char* file_and_line)
: function_name_(function_name), file_and_line_(file_and_line) {}
Location::Location() : function_name_("Unknown"), file_and_line_("Unknown") {}
Location::Location(const Location& other)
: function_name_(other.function_name_),
file_and_line_(other.file_and_line_) {}
Location& Location::operator=(const Location& other) {
function_name_ = other.function_name_;
file_and_line_ = other.file_and_line_;
return *this;
}
std::string Location::ToString() const {
char buf[256];
snprintf(buf, sizeof(buf), "%s@%s", function_name_, file_and_line_);
return buf;
}
總結(jié)
- Location類記錄對(duì)象產(chǎn)生的函數(shù)名,文件名+行號(hào)信息。這些信息由C++編譯器內(nèi)置宏 __FUNCTION __,__FILE __,__LINE __提供,編譯期被轉(zhuǎn)化為常量字符串。
- Location類的構(gòu)造函數(shù)并不執(zhí)行內(nèi)存拷貝在其內(nèi)部存儲(chǔ)上述常量字符串的信息,而是簡(jiǎn)單的記錄上述常量字符串的地址,同時(shí),也沒有提供析構(gòu)函數(shù)以銷毀上述字符串所占空間。這樣可以避免反復(fù)的進(jìn)行內(nèi)存申請(qǐng),拷貝和釋放,以提升效率。
- 實(shí)際應(yīng)用上,通常通過宏定義RTC_FROM_HERE來(lái)產(chǎn)生Location對(duì)象,記錄此時(shí)Location對(duì)象出生位置。