読者です 読者をやめる 読者になる 読者になる

deleteをなくすには

deleteコードを減らすことは、複雑なコードの保守やリソースリークの観点で望ましい。

下のようなコードでdeleteを消したい。
なお、new[]で確保した配列は、delete[]で削除しなければいけないことに注意。

class C
{
  public:
    char* buf;
    unsigned int size;
    C( char* p, unsigned int sz )
     : buf(new char[sz]), size(sz) // new[]で確保
    {
      memcpy(buf, p, sz);
    };
    ~C() { delete[] buf; } // delete[]で削除
};

void test_code()
{
  vector<C> v;
  char* m = new char[100]; // new[]で確保
  C a(m, 100);
  v.push_back(a);
  delete[] m; // delete[]で削除
}

unique_ptrを用いてみよう。unique_ptrも配列については配慮が必要だ。
代入演算子で余分な削除が起きている(reset)。

class C
{
  public:
    unique_ptr<char[]> buf;
    unsigned int size;
    C( unique_ptr<char[]>& p, unsigned int sz )
     : buf(move(p)), size(sz) {}
    C( const C& lhs )
     : buf(new char[lhs.size]), size(lhs.size)
    {
      memcpy( buf.get(), lhs.buf.get(), size );
    }
    const C& operator=( const C& lhs )
    {
      size = lhs.size;
    buf.reset( new char[size] );
    memcpy( buf.get(), lhs.buf.get(), size );
    return *this;
    }
    ~C() {}
};

void test_code()
{
  vector<C> v;
  unique_ptr<char[]> m( new char[100] );
  C a(m, 100); // mからaへ配列ポインターは移動する
  v.push_back(a);
}

配列ポインターの移動のためにコンストラクターを追加したということもあるが、コード数が増えてかえってメンテがしにくいような気もする。

このような場合は素直にvectorを使えば簡易になる。

class C
{
  public:
    vector<char> buf;
    C() : buf() {}
    C( vector<char> &p ) : buf(p){}
    ~C() {}
};

void test_code()
{
  vector<C> v;
  vector<char> m(100);
  C a(m);
  v.push_back(a);
}


文字列であればstringを用いることもできる

class C
{
  public:
    string buf;
    C() : buf() {}
    C( string &p ) : buf(p){}
    ~C() {}
};

void test_code()
{
  vector<C> v;
  string m;
  m.resize(100);
  C a(m);
  v.push_back(a);
}