インスタンスの構築に非常に費用がかかるオブジェクトのstd::mapがあります。(実際には、データベースへの複数のアクセスが必要です。)
マップの要素にアクセスするか、存在しない場合は作成します。これはstd::map :: insertの仕事のように聞こえますが、高価なオブジェクトが不必要に構築され、要素が存在する場合は破棄される点が異なります。説明する:
#include <iostream>
#include <map>
#include <string>
struct CexpensiveObject
{
CexpensiveObject(const char* args="default"):args_(args)
{
std::cout << "Constructor: CexpensiveObject(" << args << ")" << std::endl;
}
CexpensiveObject( const CexpensiveObject& other )
{
std::cout << "Copy Constructor: CexpensiveObject other.args_ = " << other.args_ << "." << std::endl;
args_ = other.args_;
}
~CexpensiveObject()
{
std::cout << "Destructor: CexpensiveObject args_ = " << args_ << "." << std::endl;
}
const char* args_;
};
// entry point
int main()
{
typedef std::map<std::string, CexpensiveObject> mymaptype;
mymaptype mymap;
std::pair<mymaptype::iterator, bool> insertionResult;
std::cout << "First insertion" << std::endl;
insertionResult = mymap.insert( mymaptype::value_type( "foobar", CexpensiveObject("first") ) );
std::cout << "Was it inserted? " << (insertionResult.second?"yes":"no") << std::endl;
std::cout << "Second insertion" << std::endl;
insertionResult = mymap.insert( mymaptype::value_type("foobar", CexpensiveObject("second") ) );
std::cout << "Was it inserted? " << (insertionResult.second?"yes":"no") << std::endl;
}
結果:
First insertion
Constructor: CexpensiveObject(first)
Copy Constructor: CexpensiveObject other.args_ = first.
Copy Constructor: CexpensiveObject other.args_ = first.
Destructor: CexpensiveObject args_ = first.
Destructor: CexpensiveObject args_ = first.
Was it inserted? yes
Second insertion
Constructor: CexpensiveObject(second)
Copy Constructor: CexpensiveObject other.args_ = second.
Destructor: CexpensiveObject args_ = second.
Destructor: CexpensiveObject args_ = second.
Was it inserted? no
Destructor: CexpensiveObject args_ = first.
予想以上にコピーと破棄がありますが、重要なことに、インスタンスCexpensiveObjectが構築され、同じキーを持つ要素がmaに存在する場合は破棄されます。
std :: map :: insertを誤用していますか、それともCexpensiveObjectインスタンスをインスタンス化する前に、std :: map :: findを使用して、同じキーを持つ要素が存在するかどうかを確認する必要がありますか?