我有一個rapidjson包裝,做以下的不必要的副本:如何防止物體
class ADocument
{
void setJson(const char *data) { m_D.parse(data); }
AData operator[](const char *key) const
{
const rapidjson::Value *value = rapidjson::Pointer(key).Get(m_D);
if(value)
return AData(value);
else
return AData(&m_D);
}
private:
rapidjson::Document m_D;
};
和AData
類是這樣的:
class AData
{
public:
Adata(const rapidjson::Value *val) : m_Value(val) {}
operator QString() const { return m_Value.IsString() ? m_Value.GetString() : QString(); }
private:
const rapidjson::Value *m_Value;
};
而且整個事情是這樣調用:
ADocument doc;
doc.setJson("{\"Hello\":{\"Hello\":\"test\"}}");
QString str = doc["/Hello/Hello"];
時
str
變爲 「測試」
。
現在,通過調試這個代碼我發現該AData
對象以某種方式移動 - 的operator QString()
會從在不同的存儲器位置的對象比原始AData
對象調用中的ADocument
的operator[]
構造。正則構造函數被調用一次。但可能是copy-elision只是在內存中移動相同的對象。
然而,當我定義的規則的三/ 5方法之一,如AData
析構函數不改變任何東西(和析構函數什麼也不做本身),那麼operator QString()
上調用同一對象(同一內存位置),其在ADocument
的operator[]
中構建。
即使當我實現了所有可想象的構造函數和運算符(move,copy,assign ...)時,它們中的任何一個都不會被調用,但結果是相同的 - 只創建一個對象。
這是怎麼回事?我想了解它。
此外,如何改變這個實現,以便儘可能提高性能和內存效率(=最小副本等)?或者,也許我真的很擔心沒有什麼,我所看到的僅僅是一些編譯器優化?
什麼是AConstData? –
@AlanStokes對不起,錯字。我從我的源代碼複製了我實際上有兩個類AData和AConstData的代碼。我用後者進行了一些測試,但它們都是相同的。 – Resurrection
聲音像複製elision正在按預期工作,有什麼問題?我認爲你不用擔心,應該讓編譯器完成它的工作。 –