多重繼承的順序
當一個類別繼承自多個類別時,它的多個父類別的constructor是會依照繼承順序被呼叫的。
以下是TensorRT/samples/common/logging.h
裡LogStreamConsumer
類別的定義:
class LogStreamConsumer : protected LogStreamConsumerBase, public std::ostream
{
public:
//! \brief Creates a LogStreamConsumer which logs messages with level severity.
//! Reportable severity determines if the messages are severe enough to be logged.
//此處initializer list的順序:先LogStreamConsumerBase後std::ostream
LogStreamConsumer(Severity reportableSeverity, Severity severity)
//LogStreamConsumerBase(stream, prefix, shouldLog)
: LogStreamConsumerBase(severityOstream(severity), severityPrefix(severity), severity <= reportableSeverity)
//mBuffer繼承自LogStreamConsumerBase
//注意這裡是先呼叫LogStreamConsumerBase建構子,
//使得mBuffer指向一個有效的位置後,
//才使用mBuffer來初始化ostream
, std::ostream(&mBuffer) // links the stream buffer with the stream
, mShouldLog(severity <= reportableSeverity)
, mSeverity(severity)
{
}
//...
}
由於在繼承順序中LogStreamConsumerBase
先於std::ostream
:
class LogStreamConsumer : protected LogStreamConsumerBase, public std::ostream
,所以會先呼叫LogStreamConsumerBase
的建構子:
LogStreamConsumerBase(severityOstream(severity), severityPrefix(severity), severity <= reportableSeverity)
以下是LogStreamConsumerBase
建構子的定義:
LogStreamConsumerBase(std::ostream& stream, const std::string& prefix, bool shouldLog)
: mBuffer(stream, prefix, shouldLog)
{
}
在這一步會初始化LogStreamConsumer
的成員變數mBuffer
。
在LogStreamConsumerBase
建構子返回後,接著才調用std::ostream
的建構子:
std::ostream(&mBuffer)
可以看到這一步需要mBuffer
這個成員變數,這也是為什麼在代碼注釋中強調LogStreamConsumerBase
及std::ostream
的繼承順序不能被替換的原因。