下面的代码使用地图中unique_ptr的引用来填充对象。来自unique_ptr的后续引用不会显示更新的痕迹。
XSSFWorkbook :: CreateCellStyle 是 XSSFCellStyle :: CreateCellStyle 工厂函数的客户端。它将 XSSFCellStyle 对象存储在 UPTR__CellStylesMap 中,并返回对它的引用。
XSSFWorkbook :: GetStylesheetXml()稍后获取对每个 XSSFCellStyle 的引用,并使用它来输出XML。
XSSFWorkbook.cpp
// ****************************************************************************
// CreateCellStyle
// ****************************************************************************
XSSFCellStyle&
XSSFWorkbook::CreateCellStyle()
{ map<int, unique_ptr<XSSFCellStyle>>::iterator iter__CellStylesMap;
unique_ptr<XSSFCellStyle> uptr__XSSFCellStyle = nullptr;
uptr__XSSFCellStyle = XSSFCellStyle::CreateCellStyle();
UPTR__CellStylesMap->insert( make_pair( UPTR__CellStylesMap->size(), move( uptr__XSSFCellStyle ) ) );
iter__CellStylesMap = UPTR__CellStylesMap->find( UPTR__CellStylesMap->size() - 1 );
return *iter__CellStylesMap->second
}
// ****************************************************************************
// GetStylesheetXml
// ****************************************************************************
string
XSSFWorkbook::GetStylesheetXml()
{ map<int, unique_ptr<XSSFCellStyle>>::iterator iter__CellStylesMap;
string str___CellStyleXfsXml = "";
// ========================================================================
// Build the XML for the Cell Styles.
// ========================================================================
if( UPTR__CellStylesMap->size() > 0)
{ str___CellStyleXfsXml += "<cellStyleXfs count=\"" + ConvertToString( UPTR__CellStylesMap->size() ) + "\">";
iter__CellStylesMap = UPTR__CellStylesMap->begin();
while( iter__CellStylesMap != UPTR__CellStylesMap->end() )
// { str___CellStyleXfsXml += iter__CellStylesMap->second->GetXml();
{ XSSFCellStyle& xssf__CellStyle = *iter__CellStylesMap->second;
str___CellStyleXfsXml += xssf__CellStyle.GetXml();
iter__CellStylesMap++;
}
str___CellStyleXfsXml += "</cellStyleXfs>";
...
}
/ ****************************************************************************
// GetXml
// ****************************************************************************
string
XSSFWorkbook::GetXml()
{ string str___WorkbookXml = "";
str___WorkbookXml += "<workbook><sheets><sheet name=\"1\" sheetId=\"1\" r:id=\"rId1\" /></sheets></workbook>";
str___WorkbookXml += GetStylesheetXml();
...
return str___WorkbookXml;
}
WinMain 中的此代码调用 XSSFWorkbook :: GetXml(),然后调用 XSSFWorkbook :: GetStylesheetXml()以获取对 XSSFCellStyle 对象并打印其XML。
XSSFCellStyle xssf__CellStyle = xssf__Workbook.CreateCellStyle();
xssf__CellStyle.SetApplyAlignment( true );
uptr__OoxmlTester->SetOoxml( xssf__Workbook.GetXml() );
它返回了 XSSFCellStyle :: XSSFCellStyle()初始化列表中设置的默认值,即使cout语句显示 XXSFCellStyle :: SetApplyAlignment()设置了ApplyAlignment属性正常。
但是使用 XSSFCellStyle 引用
uptr__OoxmlTester->SetOoxml( xssf__CellStyle.GetXml() );
返回更新后的值(当然)。
更改 XSSFWorkbook :: CreateCellStyle(),以便返回原始指针
XSSFCellStyle*
XSSFWorkbook::CreateCellStyle()
...
return iter__CellStylesMap->second.get();
和 WinMain 同样
XSSFCellStyle* ptr___CellStyle = xssf__Workbook.CreateCellStyle();
ptr___CellStyle->SetApplyAlignment( true );
uptr__OoxmlTester->SetOoxml( xssf__Workbook.GetXml() );
修复了更新的值,显示指针版本确实更新了 UPTR__CellStylesMap 中的 XSSFCellStyle 实例。
我不知道 XSSFWorkbook :: CreateCellStyle()的参考版本如何为我提供 XSSFCellStyle 对象的引用,而不是 UPTR__CellStylesMap < / strong>(副本?),而 XSSFWorkbook :: GetCellStyleXml() 中的相同代码获取对 XSSFCellStyle 对象的引用的 UPTR__CellStylesMap
因为没有NULL XSSFCellStyle 这样的东西,我已经放弃了引用版本而转而使用unique_ptr版本,但是我仍然想知道如何永远不会重新创造这个谜。
P.S。我的编码风格打破常规,让一些人感到不安。请不要让它打扰你。
答案 0 :(得分:2)
是的,您正在此行中创建副本:
XSSFCellStyle xssf__CellStyle = xssf__Workbook.CreateCellStyle();
应该注意的是,正如您暗示的那样,副本不是通过返回引用来创建的,而是通过使用返回的引用初始化新值。
如果要避免复制,则应将结果存储在引用或指针中。
XSSFCellStyle& xssf__CellStyle = xssf__Workbook.CreateCellStyle();
//or this
XSSFCellStyle* ptr__CellStyle = &xssf__Workbook.CreateCellStyle();
如果您想避免意外复制,那么您应该考虑删除XSSFCellStyle
的复制构造函数,如下所示:
XSSFCellStyle( const XSSFCellStyle&) = delete;
我知道这是一个风格决定,但我不认为以Create
开头的函数应该返回参考。