【问题标题】:Dynamic vs non-dynamic class members动态与非动态类成员
【发布时间】:2011-03-21 05:50:47
【问题描述】:

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

class A {
    type a;
};

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

在构造函数中:

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

和析构函数:

A::~A {
    delete a;
}

除了动态的需要更多代码之外,这两种方法有什么优点或缺点吗?它们的行为是否不同(除了必须取消引用的指针)还是一个比另一个慢?我应该使用哪一个?

【问题讨论】:

  • 努力拥有正确的可维护代码,然后如果需要,努力提高性能。
  • 您的第二个A 不安全;您还需要定义复制构造函数和operator=。永远不要拥有这样的指针,将它们包装起来,这样您就不需要编写 任何 特殊成员函数。

标签: c++ class dynamic variables


【解决方案1】:

有几个区别:

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

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

  3. 指针类型更难管理 - 因为它不会与类一起自动分配或销毁,您需要确保自己这样做。对于多个指针成员,这变得很棘手 - 如果您在构造函数中将所有指针成员 newing,并且在该过程的中途出现异常,则不会调用析构函数并且您有内存泄漏。最好将指针变量分配给“智能指针”容器(如std::auto_ptr立即,这样清理会自动处理(您无需担心deleteing 他们在析构函数中,通常使您根本不用编写一个)。此外,每当您手动处理资源时,您都需要担心复制构造函数和赋值运算符。

【讨论】:

  • 将智能指针容器包含(stl/boost)添加到您的项目通常会比包含您自己的头文件更多地增加您的编译时间。被认为便宜的堆栈分配比堆分配(被认为昂贵)快得多。如果您手动处理资源,为什么还要担心复制构造函数和赋值运算符?确保保留指向它们的指针而不是复制它们。 (只需将复制/分配声明为私有,您就永远不会犯错)。
【解决方案2】:

有了指针,你有更多的控制权,但也有更多的责任。从某种意义上说,您有更多的控制权,您可以更精确地决定对象的生命周期,而没有指针,生命周期本质上等于包含对象的生命周期。此外,对于指针,成员实际上可以是指针类型的子类的实例。

在性能方面,使用指针确实意味着更多的内存使用、更多的内存碎片,并且取消引用确实需要大量时间。然而,除了对性能最关键的代码之外,所有这些都不是真正值得担心的。

【讨论】:

    【解决方案3】:

    主要区别在于指针可能指向其他地方。

    编辑

    劳伦斯的回答没有错,但有点笼统。具体来说,动态分配会稍微慢一些。通过指针取消引用同样会稍微慢一些。同样,这并没有造成很大的速度损失,而且它所获得的灵活性可能非常值得。

    【讨论】:

      【解决方案4】:

      主要区别在于,如果您不使用指针,则内部成员的内存将作为分配给包含对象的内存的一部分进行分配。如果您使用new,您将获得单独的内存块(您似乎已经正确创建和销毁引用的对象)

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2012-04-13
            • 1970-01-01
            • 2018-11-30
            • 2015-11-15
            • 2022-11-29
            • 2020-07-22
            • 2019-01-10
            • 2018-12-18
            • 1970-01-01
            相关资源
            最近更新 更多