数组作为类的私有成员

fin*_*oop 14 c++ arrays

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

Mat*_*lia 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;
    }
};
Run Code Online (Sandbox Code Playgroud)

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

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
};
Run Code Online (Sandbox Code Playgroud)

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

相反,如果您希望拥有可复制对象,则必须决定是否要创建共享数组的副本(因此,只需指针副本),或者是否要为另一个对象创建新的独立数组.

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

如果您想要进行"深层复制",则必须分配新内存并将源阵列的所有对象复制到目标阵列.这不是完全无关紧要的,通常通过"复制和交换习语"来完成.

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