2
#include <array>
#include <iostream>

using namespace std;

struct SimpleDebugger
{
    SimpleDebugger(int val = 0) : x(val) {
        cout << "created" << endl;
    }

    SimpleDebugger(const SimpleDebugger &that) : x(that.x) {
        cout << "copied" << endl;
    }

    ~SimpleDebugger() {
        cout << "killed!" << endl;
    }

    int getX() const {
        return x;
    }

    void setX(int val) {
        x = val;
    }

private:
    int x;
};

array<SimpleDebugger, 3> getInts(int i)
{
    array<SimpleDebugger, 3> a;
    a[0].setX(i);
    a[1].setX(i + 1);
    a[2].setX(i + 2);
    cout << "closing getInts" << endl;
    return a;
}

SimpleDebugger (*getIntsArray(int i)) [3] {
    typedef SimpleDebugger SimpleDebugger3ElemArray [3];
    SimpleDebugger3ElemArray *sd = new SimpleDebugger3ElemArray[1];
    (*sd)[0].setX(i);
    (*sd)[1].setX(i + 1);
    (*sd)[2].setX(i + 2);
    cout << "closing getIntsArray" << endl;
    return sd;
}

ostream& operator << (ostream& os, const SimpleDebugger &sd) {
    return (cout << sd.getX());
}

int main() {
    auto x = getInts(5);
    cout << "std::array = " << x[0] << x[1] << x[2] << endl;
    auto y = getIntsArray(8);
    cout << "Raw array = " << (*y)[0] << (*y)[1] << (*y)[2] << endl;
    delete [] y;
}

出力

created
created
created
closing getInts
std::array = 567
created
created
created
closing getIntsArray
Raw array = 8910
killed!
killed!
killed!
killed!
killed!
killed!

上記のプログラムを試してstd::array、生の配列を使用するのがいかに便利かを確認しました。古いスタイルの配列を避けるのが良いスタイルであり、さらに良いのは を使用することstd::vectorです。

std::array関数getInts()が返されたときに、内部で何が起こるか知りたいです。生の配列の場合、それはポインターのコピーであり、それをクリーンアップする責任は呼び出し先にあることはわかっています。これstd::arrayは起こりませんが、どのようにデータを内部に保存し、どのようにコピーが行われるのでしょうか?

4

1 に答える 1

7

std::array唯一のデータ メンバーとして配列を含む集計です。1 つをコピーまたは移動すると、配列の各要素が新しい配列にコピーまたは移動されます。

あなたの場合、関数から返されたときにコピーが省略されています。内部では、配列が の自動ストレージに作成されmain、関数がその配列に入力します。

于 2013-01-24T19:36:27.673 に答える