在复制具有巨大数组成员的类时使用
Are pointers used when copying a class with huge array member?
我有一个存储多维数组的类作为成员。
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();
这样的对象并返回该指针会发生什么变化?
按值返回对象时,将复制实际数据(323 int
s)。编译器可能会优化删除副本(所谓的"副本省略"),但这不能保证。
如果动态分配对象并返回指向它的指针,当然不会进行复制。如果您可以访问c++ 11,请考虑返回std::unique_ptr
,以便所有权清晰,并且没有内存泄漏的机会。
在c++ 11中,您还可以通过将成员Data
转换为容器(如std::vector
)来"做得更好",该容器内部将其数据存储在堆上并具有move语义。这意味着当从函数返回时,容器将被移动而不是复制,并且数据不会重复。
当您按值返回一个对象时,该对象实际上不会被复制,相反,您的函数将直接在调用者内存中填充该对象。就好像你做了以下事情:
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;
}
你可以让它按照你想要的方式运行。如果你像这样定义一个函数…
Structure* someFunction();
将返回一个指向结构对象的指针。该对象必须分配new。例如像这样定义函数:
Structure* someFunction() {
Structure* someNewStructure = new Structure();
return someNewStructure;
}
你必须记住,这个元素是在这个函数中创建的,这个函数把销毁这个对象的"责任"转移给了调用者。通常最好避免这种情况,但对于大型数据结构则不能这样做。处理此问题的另一种方法是在类中定义复制构造函数,以便您可以按照引用的方式进行操作。如果您这样做而不定义复制构造函数:
Sturcture someFunction() {
Structure someResultStruct;
return someResultStruct;
}
当你在这种情况下调用someFunction时,如果你的类包含动态元素,或者其他复杂的数据类型,它们不能保证在返回时正确复制,你会得到奇怪的行为…除非你定义了自己的复制构造函数
- 是否可以将结构数组别名为结构成员数组?
- C++:初始化 constexpr 构造函数中的成员数组
- 使用带有参数包的数组的成员数组初始化类
- C++ 在析构函数调用之前删除的动态成员数组
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 指向具有不同大小的成员数组的指针
- 用另一个 constexpr 数组对成员数组进行大括号初始化
- 对象成员数组C++默认初始化
- 如何在构造函数中的类成员数组中分配数组值,而无需使用STD库
- 将类成员数组组合到单个数组时性能下降
- 如何将数据从公共方法添加到同一类中的私有成员数组中?
- 如何在C 中的派生类中分配数据成员数组
- C 集合构建器中类成员数组的2D数组大小
- 初始化不可复制、不可移动、显式构造类型的成员数组
- C 指针可以指向字符串文字的静态成员数组
- 成员数组位于何处
- 将对象成员数组与字符串进行比较
- 如何在 c++ 中从对象数组中获取数据成员数组
- 声明模板会员参考另一个类的模板成员数组
- C 初始化成员数组