数组作为类的私有成员

时间:2010-01-17 22:50:46

标签: c++ arrays

我正在尝试创建一个具有私有成员的类,该类是一个数组。我不知道数组的大小,直到值传递给构造函数。定义类构造函数以及.h文件中的定义以允许这个可变大小的数组的最佳方法是什么?

2 个答案:

答案 0 :(得分:11)

如果你想要一个“真正的”C风格的数组,你必须在你的类中添加一个指针私有成员,并在构造函数中为它动态分配内存(使用 new )。显然你不能忘记在析构函数中释放它。

class YourClass
{
  private:
    int * array;
    size_t size;

    // Private copy constructor operator to block copying of the object, see later
    // C++03:
    YourClass(const YourClass &); // no definition
    // C++11:
    YourClass(const YourClass&) = delete;

  public:
    YourClass(size_t Size) : array(new int[Size]), size(Size)
    {
        // do extra init stuff here
    };

    ~YourClass()
    {
        delete [] array;
    }
};

为了使这项工作更容易,您可以考虑使用智能指针(例如,C ++ 03中的boost::scoped_array或C ++ 11中的普通std::unique_ptr)在构造函数之前使用初始化列表初始化或仅在构造函数中初始化。

class YourClass
{
  private:
    boost::scoped_array<int> array; // or in C++11 std::unique_ptr<int[]> array;
    size_t size;
  public:
    YourClass(size_t Size) : array(new int[Size]), size(Size)
    {
        // do extra init stuff here
    }

    // No need for a destructor, the scoped_array does the magic
};

这两个解决方案都产生不可复制的对象(你没有指定它们是否必须是可复制的和它们的复制语义);如果不必复制类(大多数情况下都会发生这种情况),这两种情况都可以,如果你试图将一个类复制/分配给另一个类,编译器会产生错误,在第一种情况下因为默认副本构造函数已经重载了私有(或在C ++ 11中删除),在第二种情况下因为boost::scoped_arraystd::unique_ptr是不可复制的。

相反,如果您想要具有可复制对象,则必须决定是否要创建共享数组的副本(因此,只需指针副本),或者如果要为此创建新的单独数组其他对象。

在第一种情况下,在释放分配的内存之前必须非常小心,因为其他对象可能正在使用它;参考计数器是最常见的解决方案。您可以通过boost::shared_array(或C ++ 11中的std::shared_ptr)为您提供帮助,它会自动为您完成所有跟踪工作。

如果您想要执行“深层复制”,则必须分配新内存并将源阵列的所有对象复制到目标阵列。这不是完全无关紧要的,通常是通过"copy and swap idiom"完成的。

但是,最简单的解决方案是使用std::vector作为私有成员:它将自己处理所有分配/释放内容,在构造/破坏类的对象时正确构造/销毁自身。而且,它实现了开箱即用的深层复制语义。如果您需要让调用者以只读方式访问向量,那么您可以编写一个getter,它返回对const_iterator对象的constvector引用。

答案 1 :(得分:2)

使用std :: vector是最佳选择。 如果您需要将它传递给期望指向数组的指针的函数(就像GSL经常那样),您仍然可以传递&vec[0] ...