时间:2010-07-26 18:15:30

标签: c++ class dynamic variables

在C ++中,我有一个类需要保存一个可以动态分配并用作指针的成员,不管怎样,如下所示:

class A {
    type a;
};

class A {
    A();
    ~A();
    type* a;
};

并在构造函数中:

A::A {
    a = new type();
}

和析构函数:

A::~A {
    delete a;
}

除了需要更多代码的动态之外,其中任何一个都有任何优点或缺点吗?它们的行为是否不同(除了必须被解除引用的指针)或者是一个比另一个慢?我应该使用哪一个?

6 个答案:

答案 0 :(得分:5)

有几点不同:

  1. 在定义类时,必须知道每个成员的大小。这意味着您必须包含type标头,并且不能像使用指针成员那样使用前向声明(因为所有指针的大小都是已知的)。这对大型项目的#include混乱和编译时间有影响。

  2. 数据成员的内存是封闭类实例的一部分,因此它将与所有其他类成员同时在同一位置进行分配(无论是在堆栈或堆上)。这对数据局部性有影响 - 将所有内容放在同一位置可能会带来更好的缓存利用率等。堆栈分配可能比堆分配快一些。声明太多巨大的对象实例可能会更快地破坏堆栈。

  3. 指针类型管理起来比较棘手 - 因为它不会自动与类一起分配或销毁,所以你需要确保自己这样做。多个指针成员变得棘手 - 如果你在构造函数中new所有这些成员,并且在进程的中途有一个异常,析构函数不会被调用而你有内存泄漏。最好将指针变量分配给“智能指针”容器(如std::auto_ptr立即,这样就可以自动处理清理(并且您不必担心{{1在析构函数中使用它们,通常可以避免写一个)。此外,无论何时手动处理资源,都需要担心复制构造函数和赋值运算符。

答案 1 :(得分:0)

答案 2 :(得分:0)

答案 3 :(得分:0)

答案 4 :(得分:0)

使用原始指针时,您需要了解默认复制构造函数和复制赋值运算符的含义。在两种情况下都会复制原始指针。换句话说,最终会有多个对象(或原始指针)指向同一个内存位置。因此,按上述方式编写的析构函数将尝试多次删除相同的内存。

答案 5 :(得分:0)

如果成员变量应该超出对象的生命周期,或者如果其所有权应该转移到另一个对象,那么该成员应该使用“new”动态(堆)分配。如果不是,那么通常最好选择使其成为类的直接成员,以简化代码并减轻内存分配器的负担。内存分配很昂贵。