月曜日, 6月 02, 2014

C++11 - ムーブコンストラクタ

C++の特徴の一つ,ムーブコンストラクタ.rvalue参照により余計なデータのコピーを避けることができるため,大きなクラスや構造体のハンドリングに関しては高速化が期待できる.

以下の例はムーブコンストラクタを使ってトレードデータクラスをスワップする例.コピーコンストラクタと異なり,セールスパーソンのリスト及びブロブデータ(この例では簡略化の為stringで代用)の転送をしている.
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef std::shared_ptr BLOB;

class TradeData {
private:
 int _tradeId;
 vector _salesPersonIds;
 string _note;
 BLOB _blob;

public:
 TradeData(int tradeId, initializer_list salesPersonIds, string note, string blobInfo) : _tradeId(tradeId), _salesPersonIds(salesPersonIds), _note(note){
  for (auto iter = salesPersonIds.begin(); iter != salesPersonIds.end(); iter++) {
   _salesPersonIds.push_back(*iter);
  }
  _blob = make_shared(blobInfo);
 }

 virtual ~TradeData() {
 }

 const char* operator()() {
  strstream buf;
  buf << _tradeId << ":[";
  for_each(_salesPersonIds.begin(), _salesPersonIds.end(), [&buf](int id){ buf << id << ","; });
  buf << "]," << _note << "," << *_blob << "(@" << _blob << ")" <<  ends;
  return buf.str();
 }

 TradeData& operator=(TradeData&& trade) {
  _blob = trade._blob;
  trade._blob = nullptr;
  _tradeId = trade._tradeId;
  _salesPersonIds = trade._salesPersonIds;
  _note = trade._note;
  return *this;

 }

};

void SwapTrade(TradeData& td1, TradeData& td2) {

 TradeData temp = std::move(td1);
 td1 = std::move(td2);
 td2 = std::move(temp);

}

int main() {

 TradeData t1(100, { 1, 2, 3 }, "test trade1", "blobdata1..");
 TradeData t2(300, { 1 }, "test trade2", "blobdata2..");
 cout << "! before swap" << endl;
 cout << "*** tradedata1 *** " << t1() << endl;
 cout << "*** tradedata2 *** " << t2() << endl;
 SwapTrade(t1, t2);
 cout << "! after swap" << endl;
 cout << "*** tradedata1 *** " << t1() << endl;
 cout << "*** tradedata2 *** " << t2() << endl;

}


0 件のコメント: