#include <stdio.h> #include <stdlib.h> void* operator new (size_t sz) throw() { printf("global operator new\n"); return 0; } int main(int ac, char* av[]) { struct newtest { static void* operator new (size_t sz) throw() { printf("newtest operator new\n"); return 0; } void dotest() { char* a = new char; printf("a = %p\n", a); } }; newtest t; t.dotest(); newtest* t2 = new newtest; };
実行結果
global operator new a = (nil) newtest operator new
// 参照型のインスタスをもつクラス struct Hoge { int& instance_; Hoge(int& i) : instance_(i) {} Hoge(const Hoge& h) : instance_(h.instance_) {} bool operator < (const Hoge& h) const { return instance_ < h.instance_; } };
std::vectorに入れてみる
std::vector<Hoge> vectorhoge; int h1 = 1; vectorhoge.push_back(h); // コンパイルエラー
operator =がないとvector::push_backはできない
listならOK
std::list<Hoge> listhoge; int h1 = 1; listhoge.push_back(h); // OK
Hoge operator = (const Hoge& h) { memcpy(this, &h, sizeof(Hoge)); return *this; }
Hoge operator = (const Hoge& h) { this->~Hoge(); new (this) Hoge(h); return *this; }
#include <cstdio> #include <list> #include <vector> #include <algorithm> #include <functional> #include <iostream> // 参照を持つクラスのswap namespace { struct Hoge { int& instance_; Hoge(int& i) : instance_(i) {} Hoge(const Hoge& h) : instance_(h.instance_) {} // コピーコンストラクタとnewの第二構文を使った初期化を使って実現する。 // 例外安全ではない。デストラクタ・コピーコンストラクタが例外を投げない // スレッドセーフではない。スレッドセーフにするには排他処理が必要。 Hoge& operator = (const Hoge& h) { if (this != &h) { // 自己代入でない this->~Hoge(); // thisを破棄 デストラクタは例外を投げない // ここで他のスレッドがthisを参照すると破綻する。シングルスレッド限定! try { new(this) Hoge(h); } catch (...) { assert(false); // 例外が投げられたら停止 } } return *this; } // リファレンスタイプのインスタンスは通常の方法ではswapできないので、 // コピーコンストラクタとnewの第二構文を使った代入の=を使って実現する。 // 例外安全ではない。コピーコンストラクタが例外を投げないことが前提 void swap(Hoge& h) { Hoge tmp(h); // hをコピー h = *this; *this = tmp; } bool operator < (const Hoge& h) const { return instance_ < h.instance_; } }; // output用 void print(const Hoge& h) { printf("%d\n", h.instance_); } } int main(int argc, char* argv[]) { int i1 = 1; int i2 = 2; int i3 = 3; Hoge h1(i1), h2(i2), h3(i3); std::vector<Hoge> vectorhoge; vectorhoge.push_back(h3); // operator =がないとvector::push_backはでき ない vectorhoge.push_back(h2); vectorhoge.push_back(h1); std::back_inserter(vectorhoge) = h1; std::sort(vectorhoge.begin(), vectorhoge.end()); // operator =がないと vector::sortはできない std::cout << "vector sort" << std::endl; std::for_each(vectorhoge.begin(), vectorhoge.end(), print); std::list<Hoge> listhoge; listhoge.push_back(h3); listhoge.push_back(h2); listhoge.push_back(h1); std::back_inserter(listhoge) = h1; listhoge.sort(); std::cout << "list sort" << std::endl; std::for_each(listhoge.begin(), listhoge.end(), print); return 0; }