vectorの気遣い

vectorで(ポインタではなく)オブジェクト自体を取り扱う場合、push_backしたときに次のことが行われています。

  • push_backの対象となるオブジェクトをコピーコンストラクタでコピー
  • 既にpush_back済みのものがあれば、再びコピーコンストラクタでそのコピーを作り、元々コピーしてあったものをデストラクタで始末する。

実際にコードを書いて確認してみました。
まずは、クラス定義から。

class Hoge
{
public:
  int num;
  Hoge(int num);
  Hoge(const Hoge& me);
  ~Hoge();
  void printAbc(void);
};

Hoge::Hoge(int aNum)
{
  num = aNum;
  printf("constructer %d\n", num);
}

Hoge::Hoge(const Hoge& me) : num(me.num)
{
  printf("copy constructer %d\n", num);
}

Hoge::~Hoge()
{
  printf("destructer %d\n", num);
}

実際にvectorを使ってクラスHogeのオブジェクトを操作してみます。

int main(int argc, char** argv)
{
  Hoge sample1(1);
  Hoge sample2(2);
  std::vector<Hoge> iremono;

  iremono.push_back(sample1);
  iremono.push_back(sample2);

  return 0;
}

コンパイルして実行しますと、次のような結果が得られます。

constructer 1
constructer 2
copy constructer 1
copy constructer 2
copy constructer 1
destructer 1
destructer 1
destructer 2
destructer 2
destructer 1

最初のコンストラクタ二つは、ソースの3,4行目によるものです。このコンストラクタに対するデストラクタは、最後の二つで、mainを抜ける際に、ローカル変数であるsample1,sample2に対して発生しています。
最初のコピーコンストラクタは一回目のpush_back時に、つまりsample1のpush時に発生しています。そして次のコピーコンストラクタは二回目のpush_back時、つまりsample2のpush時に発生しています。直後、一回目のコピーコンストラクタでコピーされたもののコピーが発生しています。そして、次のデストラクタで一回目のpush_back時にコピーしたもののデストラクタが発生しています。
つまり、push_back時にはpushしたものがコピーされるだけではなく、既に入っているものも同時にコピーし直されます。

そして、次のデストラクタ二つはローカル変数iremonoがmainから抜けるとき、中のオブジェクトのデストラクタが発生することを示しています。このように明示しなくても中のオブジェクトをデストラクトしてくれるのは、vectorで(ポインタではなく)オブジェクト自体を持つことのメリットだと思います。ちなみに、このときのデストラクタの発生する順番はpush_backした順番です。

私はvectorでオブジェクト自体を持つのは避けるようにしています。上記のようなメリットはあるのですが、vectorの「気遣い」であるコピーコンストラクタ、デストラクタに、反って戸惑わされる恐れがあるからです。それよりも「後始末をしっかりする」ことさえ注意していればよい「ポインタを持つ」方が楽なのでは、と考えています。

Androidでスクリーンショット

以前iPhoneユーザがお手軽にスクリーンショットを撮っているのをみて、Androidでもできないかと調べてみたのですが、手順がややこしくとても実用的なものではなかったので諦めていました。
ところが今日、何気にAndroidのSDカードの直下を見てみると「screen shot」という見慣れないフォルダができているのを発見しました。中を見ると、2週間ほどまえの日付のホーム画面の画像がPNGで保存されていました。
さっそく再調査してみたところ、一部機種(私はGALAPAGOS SoftBank 003SHを使っています。)はホームボタンと電源ボタンの同時押しでスクリーンショットが撮れるとのこと。
試してみると見事に撮れました。

2週間ほど前に意図せず撮れていたスクリーンショットが功を奏したかたちとなりました。

MacBook Pro(15-Inch, Early 2011)のメモリ4GB→16GB増設

MacBook Pro(15-Inch, Early 2011)

を現在のSnow Leopard から Mountain Lionにしようと思ったのですが、どうも現在の4GBのメモリでは苦しそうだということが、いろいろな方のブログなどからわかりました。

そこで今回のメモリの増設となりました。このMacBook Proの公式な対応メモリ容量のMAXは8GBなのですが、いろいろな方の情報だと16GBも可能、とのことでしたので、8GBメモリの二枚挿し、16GBに増設することにしました。

肝心のメモリは、Transcend JetRam ノートPC用増設メモリ PC3-10600(DDR3-1333) 8GB 永久保証 JM1333KSH-8G

を2枚購入しました。Tポイントも使えましたので、合計5000円ほどで購入しました。
また、裏ぶたをあけるためのドライバを100円ショップで購入しました。

数日後、メモリが無事届きました。
届いたメモリ

さっそく裏ぶたをはずそうとしたのですが、どうしても緩められないネジがありました。100円ショップで購入した#00のプラスドライバーではグリップに力が入らないためのようで、しっかりしたドライバーを買う必要があると判断し、
VESSEL(ベッセル) マイクロドライバー No.9900 +00×75

を購入しました。

数日後、ドライバーが無事届きました。
届いたドライバー

半信半疑でしたが、届いたドライバーを使うとあっけなく裏ぶたを開けることができました。
蓋開け直後

中央部にメモリのスロットがあり、両サイドのフックを広げて外すと二枚重なっているのがわかります。
二枚重なっているメモリ

二枚を届いたメモリと交換し、裏ぶたを閉めて、動作確認をしました。
mac_16gb

BootCampに入れているWindows7でも当然16GBになっています。
win_16gb

メモリ増設成功です。