C++类成员数据的首选分配方式是什么?

3
假设我有一个类来分配一些任意的成员数据。我知道有两种常见的方法(当然还有其他方法):
class A
{
    public:
        A();
        ~A();

        //Accessors...
    private:
        B *mB;
}

A::A()
{
    mB = new B();
}

A::~A()
{
    delete B;
}

对比...

class A
{
    public:
        //Accessors...
    private:
        B mB;
}

假设A本身将由使用者代码在堆上分配。
通常情况下,哪种方法更好?我知道具体情况会鼓励采用其中一种方式,但在没有这些要求的情况下,是否有一种更好的方式?它们之间的权衡是什么?

除非知道'B'是否也有可能依赖于'A',否则无法回答这个问题。 - Chubsdad
默认复制/赋值时指针会出现有趣的问题。:-X - Anycorn
4个回答

9
第二种方法是首选。除非您明确需要一个变量位于堆上或具有比其容器更长的生命周期,否则请不要使用new/delete。在我看来,C++值类型更易于管理,且需要担心的错误情况较少。

4

这要看情况。

一般来说,如果B比较大且笨重,则传递指向B的指针比传递B本身更容易。因此,如果B经常与A分离(例如A交换B),则第一种方法更好。

使用指针还可以减少依赖关系。如果做得对,A.hh可以不指定B是什么或做什么(即A.h不需要#include "B.hh"),因此依赖于A.hh的东西不一定依赖于B.hh

使用指针的代价是多了一层机制以及遗失对象、双重删除和未初始化指针的危险,因此除非它在您的情况下确实有益,否则不应使用。一些人迷恋指针技术,并随处使用;如果他们想成为更好的程序员,就必须摆脱这种习惯。


0
通常情况下,更喜欢直接组合(第二个选择)。在这种情况下,没有泄漏内存的机会,并且对象完全位于连续的内存块中,允许更好的缓存局部性。
如果您正在实现PIMPL或需要使用多个可能的类类型(通过继承),则可以使用第一种选项。在这种情况下,一定要使用智能指针(例如boost::shared_ptr)来管理内存。

0

这取决于你要寻找什么。

为了简单起见:不要使用指针。因此第二个选择。

这样更容易管理(无需担心内存管理、深度复制、深度常量等等)。

但是有时您可能需要动态分配属性:

  • 如果需要多态性(否则会截断)
  • 如果想减少依赖关系(在头文件中)--> 请参见PIMPL here

即使在这种情况下,也要将责任交给智能管理器(智能指针、专用的pimpl类等)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接