トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
C++
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索

___

■ OperatorNew


    new 演算子の処理は自前で定義することでカスタマイズできる。



___

■ perator newをオーバーライドする

メモリを確保する処理をオーバーライドする。
    void *operator new( size_t sz ) {
      gCnt ++;
      return malloc( sz );
    }

POINT ペアになるように operator delete も定義する。
    void operator delete( void *p ) {
      gCnt --;
      free( p );
    }

___

■ 追加の情報をわたす

operator new() は引数に応じたものが呼ばれる。 最初の size_t 引数は必須の項目。その後は任意。 デバッグ情報をうけとる operator new では 2つの引数を追加する。
    operator new( size_t sz, const char *file, int line ) {

    }
    int *a = new( __FILE__, __LINE__ ) int[4];
メンドイのでマクロにする。
    #define NEW  new( __FILE__, __LINE__  )

    int *a = NEW int[4];
___

■ mallocする領域に追加する

確保するメモリの前後にマークをつけることでメモリ破壊を検地する。
    void *operator new( size_t worksz ) {
      int sz = worksz + sizeof( int ) * 4;

      char *p = (char *)malloc( sz );

      int *pt = (int *)p;

      pt[0] = worksz;
      pt[1] = 12345678;
      
      pt = p + sizeof( int ) * 2 + worksz;
      pt[0] = 12345678;
      
      return p + sizeof(int)*2;
    }    

___

■ malloc.のように失敗しても NULL を返さない


    //  これは OK
    void *p = malloc( 1024*1024*1024 );
    if ( p == 0 ) {
      printf("malloc fail\n");
    }

    // new は失敗すると Exception をなげる
    class Test{
      int i;
    };

    try {
      Test *p = new Test[350*1000*1000];
    }
    // ここで補足しないと 
    catch(...){
      printf("fail new\n");
    }        
// NULL を返したいなら new(std::nothrow) を利用する // 過去の互換性をとるための new
  int *p = new( std::nothrow ) int[350*1000*1000];
  
  if ( p == NULL ) {
    printf( "new fail" );
  }
// WARNING // Exception を投げないのは Memory 確保のときだけ // その後の ctor で投げられたら OUT


    class Test
    {
      int i;
     public:
      Test(){
        printf("Test ctor\n");
        throw( bad_alloc() );
      }
    }; 


    // Memory 確保に失敗すると NULL をかえす
    //  成功すると ctor をよぶ -> ここで Exception を投げられる可能性はある
    Test *p = new( std::nothrow ) Test[1*1000*1000];

    if ( p == NULL ) {
      printf("new fail\n");
    } 


___

■ 宣言しなくてもメンバ関数はstatic扱い

DESC メモリブロックの指定は外からする必要あり
    void *operator new( size_t t ) {
      // `this' is unavailable for static member functions

      // MemBlk を取得する関数に this はない
      dpi( this->data );

      // この後に constructor が実行される。
      return work;
    }
POINT static な GlobalNew は FileScope で利用される -> ! WARNING がでる. ! LocalDelete() を定義しても, dtor は呼ばれるらしい [ System ] -> Cls::dtor() -> Cls::operator delete(); という順番らしい. operator delete() はあくまで, Memory の解放のためにあるようだ. class Foo { public: ~Foo(){ dps("Foo dtor"); } // うばう. dtor は走る. void operator delete( void*p ){ printf("operator delete"); } }; WARNING: WARNING C4211: 非標準の拡張機能が使用されています : EXtern が static に再定義されました。 POINT 優先順 Global < FileScopeGlobal < ClassLocal の operator new 実は, new, delete は Memory を確保に失敗すると Exception を投げる EXception を投げる際も, new, delete が呼ばれる どこから new, delete をどこから利用しているかわからない. だから Exception を投げずに, NULL を返す仕様の方がよいかも Constuctor は new XXX の形でしか呼べない. ? size_t 以外の OperatorNew ( PlacementNew ) を利用した場合は, Overload になるのかな ? -> 隠ぺいされてしまう -> 隠蔽されない. ! Build できてしまう. WARNING C4345: 動作変更 : 形式 () の初期化子で構築される POD 型のオブジェクトは [ 既定初期化 ] されます この WARNING の考察. 次の条件の際におきる. DefaultCtor 未定義. && Foo() // () ありの ctor ( -> 0 初期化. ) && PlacementNew の定義. () なしならば, 0 初期化されない. SOL ctor で () をつけない. ( 2 種類ある ) 要は PlacementNew ないで, Object を初期化しても DefaultCtor で 0 Clear しますよ ! と言っている POINT PlacementNew をする場合は, ctor をしっかり定義すること STL は Cpp の CMP に必ず付属する. ( だから PS3 でもある. ) -> STL の Allocator 指定は, 要は, Memory をここからとってよ ! という意味. 自分の中で, new する場合は, 別途の領域から取得する. 実は operator new は Method なので, OverWrite, OverLoad が可能. -> public に Access されるので, public にする必要がある. Class 内で宣言したものは, 要は, Object の生成空間を指定する際に使う. -> さらに継承されるので, 継承によって, Pool を指定することもできる. // Memory を指定するための クラスを用意してもいい. // 継承すれば, OK ! ( MultiInheritance ) // // MemorySelect を利用したもの同士を継承してしまうと競合がおきる. // class MemorySelect { }; 派生先で定義した場合は, OverWrite される. -> しない場合は, bCls で[ 定義したもの.ま.で ]さかのぼる. operator new( size_t , ... ) 引数リスト自体を カスタムすること可能 -> 逆に呼び出したい new の Signature にあうように指定する必要あり. ClassLocalNew を定義した場合は, new Foo; では GlobalNew は見に行かない. -> このあたりは Scope の解決の問題かも.
    operator new ( size_t sz, void *memBlk ) {
        ...
    }
    new( gWork ) Array();
Class の外で定義したものは, Global( 誰からも見れる )New, GlobalDelete となり, new , delete 時に call される. -> operator new も operator の考えに基づけば, 関数のひとつ. さらに system の new も malloc() を呼ぶらしい. ? -> ので自分で NewGbl を overwrite する場合も, malloc 利用して OK C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\new.cpp void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { // try to allocate size bytes void *p; // malloc() している. while ( (p = malloc(size)) == 0 ) if (_callnewh(size) == 0) { // report no memory static const std::bad_alloc nomem; _RAISE(nomem); } return (p); }
___

■ 初期化リストは必ず記述

WARNING 仮引数は _data とする
      foo()::foo(int _data) 
      : data(_data)


NINJAIDX 12