【问题标题】:std::array copy semanticsstd::array 复制语义
【发布时间】:2013-01-25 03:48:27
【问题描述】:
#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 中不会发生这种情况,但它如何在内部存储数据以及如何进行复制?

【问题讨论】:

  • 如果您使用的是 g++,请使用 -fno-elide-constructors 再次尝试测试以获得另一个可能的输出。
  • @Robᵩ 哇,显示 6 个“已复制”,感谢您的旗帜!

标签: c++ arrays c++11 copy copy-constructor


【解决方案1】:

std::array 是一个聚合,包含一个数组作为其唯一的数据成员。复制或移动一个会将数组的每个元素复制或移动到新数组中。

在您的情况下,副本在从函数返回时被省略;在后台,数组是在main 的自动存储中创建的,函数会填充该数组。

【讨论】:

  • +1 std::array 的这个属性不会降低旧式数组的性能吗?
  • @legends2k:对于内置数组可以做的所有事情,它的性能与内置数组完全一样。它也是可复制和可移动的。
  • 我想我明白了,一个永远不会返回一个内置数组,或者只是一个不能,只是因为std::array 可以返回,返回它会降低它的性能,因为任何容器类型都是如此。我的推断是否正确?
  • @legends2k:确实,移动语义和复制/移动省略(或 ​​RVO,如果您愿意)是两种不同的现象。如果可能,从函数返回的值将被移动,因此无需使用std::move;并且编译器应该尽可能地省略复制/移动。
  • 现已澄清,感谢您耐心回复我所有的cmets :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 2013-07-19
相关资源
最近更新 更多