复制具有大型数组成员的类时是否使用指针?

时间:2013-05-17 15:27:59

标签: c++ arrays pointers memory return

我有一个存储多维数组作为成员的类。

struct Structure
{
    Structure()
    {
        memset(Data, 0, sizeof Data);
    }

    int Number;
    int Data[32][32][32];
}

当我编写一个返回此Structure对象的函数时,如果复制了Data成员或只是传递了一个引用,那么是所有字节吗?

Structure Create(int Parameter)
{
    Structure structure;

    // modify structure based on parameter
    // ...

    return structure;
}

如果这导致复制整个数据块,我该怎样做得更好?如果像Structure *structure = new Structure();那样在堆上分配对象并返回指针会改变什么呢?

3 个答案:

答案 0 :(得分:3)

按值返回对象时,将复制实际数据(32 3 int s)。编译器可能会优化副本(所谓的“复制省略”),但这绝不保证。

如果动态分配对象并返回指向它的指针,当然不会有复制。如果您有权访问C ++ 11,请考虑返回std::unique_ptr,以便明确所有权,并且不存在内存泄漏的可能性。

在C ++ 11中,您还可以通过将成员Data转换为一个内容(例如std::vector)来“做得更好”,该内容将其数据内部存储在堆上并具有移动语义。这意味着从函数返回时,将移动容器而不是复制容器,并且不会复制数据。

答案 1 :(得分:1)

当您按值返回对象时,实际上不会复制该对象,而是您的函数将直接在调用者内存中填充该对象。就好像你做了以下事情:

Structure s;
Create(Parameter, &s);

虽然默认构造函数甚至没有被调用好一点。这称为“返回值优化”。虽然它不受标准的保护,但它由所有主流C ++编译器执行(包括clang,gcc和Visual C ++)。

如果你想在堆上,那么这样做:

Structure * Create(int Parameter)
{
    Structure * structure = new Structure();
    return structure;
}

但最好使用智能指针。如果您使用的是c ++ 11,则可以使用std::unique_ptr

std::unique_ptr<Structure> Create(int Parameter)
{
    auto structure = std::unique_ptr<Structure>(new Structure());
    return structure;
}

答案 2 :(得分:0)

你可以按照自己的意愿行事。如果你定义这样的函数......

Structure* someFunction();

将返回指向Structure对象的指针。必须使用new分配此对象。例如,定义这样的函数:

Structure* someFunction() {
    Structure* someNewStructure = new Structure();
    return someNewStructure;
}

你必须记住,这个元素是在这个函数中创建的,并且该函数正在将“对象”转移到将此对象销毁给调用者。通常最好避免这种情况,尽管它具有大型数据结构。处理此问题的另一种方法是在类中定义复制构造函数,以便您可以按引用的方式执行此操作。如果您这样做,则不定义此复制构造函数:

Sturcture someFunction() {
    Structure someResultStruct;
    return someResultStruct;
}

在这种情况下调用someFunction时,如果您的类包含动态元素或其他复杂数据类型,则无法保证在返回时正确复制它们,并且您将获得奇怪的行为......除非您定义自己的复制构造函数