在C ++中,我有一个类需要保存一个可以动态分配并用作指针的成员,不管怎样,如下所示:
class A {
type a;
};
或
class A {
A();
~A();
type* a;
};
并在构造函数中:
A::A {
a = new type();
}
和析构函数:
A::~A {
delete a;
}
除了需要更多代码的动态之外,其中任何一个都有任何优点或缺点吗?它们的行为是否不同(除了必须被解除引用的指针)或者是一个比另一个慢?我应该使用哪一个?
答案 0 :(得分:5)
有几点不同:
在定义类时,必须知道每个成员的大小。这意味着您必须包含type
标头,并且不能像使用指针成员那样使用前向声明(因为所有指针的大小都是已知的)。这对大型项目的#include
混乱和编译时间有影响。
数据成员的内存是封闭类实例的一部分,因此它将与所有其他类成员同时在同一位置进行分配(无论是在堆栈或堆上)。这对数据局部性有影响 - 将所有内容放在同一位置可能会带来更好的缓存利用率等。堆栈分配可能比堆分配快一些。声明太多巨大的对象实例可能会更快地破坏堆栈。
指针类型管理起来比较棘手 - 因为它不会自动与类一起分配或销毁,所以你需要确保自己这样做。多个指针成员变得棘手 - 如果你在构造函数中new
所有这些成员,并且在进程的中途有一个异常,析构函数不会被调用而你有内存泄漏。最好将指针变量分配给“智能指针”容器(如std::auto_ptr
)立即,这样就可以自动处理清理(并且您不必担心{{1在析构函数中使用它们,通常可以避免写一个)。此外,无论何时手动处理资源,都需要担心复制构造函数和赋值运算符。
答案 1 :(得分:0)
答案 2 :(得分:0)
答案 3 :(得分:0)
答案 4 :(得分:0)
使用原始指针时,您需要了解默认复制构造函数和复制赋值运算符的含义。在两种情况下都会复制原始指针。换句话说,最终会有多个对象(或原始指针)指向同一个内存位置。因此,按上述方式编写的析构函数将尝试多次删除相同的内存。
答案 5 :(得分:0)
如果成员变量应该超出对象的生命周期,或者如果其所有权应该转移到另一个对象,那么该成员应该使用“new”动态(堆)分配。如果不是,那么通常最好选择使其成为类的直接成员,以简化代码并减轻内存分配器的负担。内存分配很昂贵。