コンテナに格納したオブジェクト。デストラクタの呼ばれる(==破棄される)順番は?

vector なり list なりにオブジェクトをガンガン push_back していきますが、そのオブジェクトが破棄される時順番で破棄されるんだろうかと。 個人的には、末尾の要素から削除されると嬉しいんだけどなー とか思っているんですが…

実験してみました。 コンパイラは VS2005 の cl で /Ox /EHcs してます。

ソースコード (乱雑)


#include <vector>
#include <iostream>

class A
{
public:

    A(const A& a) : p(a.p){}
    A(char* a) : p(a){}
    ~A()
    {
        std::cout << p << std::endl;
    }

    char*   p;
};


int main()
{
    std::vector<A>  stlA;

    stlA.push_back("Kanaria");
    stlA.push_back("Manna");
    stlA.push_back("Misya");

    return 0;
}

出力結果


Kanaria
Kanaria
Kanaria
Manna
Manna
Kanaria
Manna
Misya
Misya
Kanaria
Manna
Misya


うぎゃあああああああああ!!



そうだよね…コンテナ内部でテンポラリオブジェクトとか作ってたりするもんね…。その破棄時にもデストラクタ呼ばれちゃうもんね…ホトト。でも、しっかり頑張ってるんだなとちょっと感動。


さて気を取り直して、 push_back した後にメッセージ入れることにしました。^^;

修正後出力結果


Kanaria
Kanaria
Kanaria
Manna
Manna
Kanaria
Manna
Misya
Misya

 --- 要らない子は全力で破棄するにょ。(…か、かしらー!?) ---

Kanaria
Manna
Misya


うーん、格納した順番で破棄されてますねぇ…。^^;
そのままだと「オブジェクトは作った順番とは 逆に 破棄するのが望ましい」というのが実現できないっぽいですね。

次に clear を呼んでみたのですが、これもデストラクタと代わらない順番で破棄されました。うーむ。


それじゃぁ、rbegin, rend の戻り値を erase に渡す? …いや erase は iterator を必要としているのに rbegin は revrese_iterator が戻り値…ムリだ。



うーん、どうすっべー。 手動でイテレーターを後ろから回って 1個ずつ erase してくー? …それもダサイよなぁー。 うーん。





………



int main()
{
    std::vector<A>  stlA;

    stlA.push_back("Kanaria");
    stlA.push_back("Manna");
    stlA.push_back("Misya");

    std::reverse(stlA.begin(), stlA.end());

    std::cout << "\n --- 要らない子は全力で破棄するにょ。(…か、かしらー!?) ---\n" << std::endl;

    return 0;
}

なるほど。



…あ、でも良く考えたらコレ、コンパイラ(というか vector 作った人)によって、破棄順番とかちがうとかそんなオチかしらー…。^^;