我正在尝试创建一个具有私有成员的类,该类是一个数组。我不知道数组的大小,直到值传递给构造函数。定义类构造函数以及.h文件中的定义以允许这个可变大小的数组的最佳方法是什么?
答案 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_array
和std::unique_ptr
是不可复制的。
相反,如果您想要具有可复制对象,则必须决定是否要创建共享数组的副本(因此,只需指针副本),或者如果要为此创建新的单独数组其他对象。
在第一种情况下,在释放分配的内存之前必须非常小心,因为其他对象可能正在使用它;参考计数器是最常见的解决方案。您可以通过boost::shared_array(或C ++ 11中的std::shared_ptr
)为您提供帮助,它会自动为您完成所有跟踪工作。
如果您想要执行“深层复制”,则必须分配新内存并将源阵列的所有对象复制到目标阵列。这不是完全无关紧要的,通常是通过"copy and swap idiom"完成的。
但是,最简单的解决方案是使用std::vector
作为私有成员:它将自己处理所有分配/释放内容,在构造/破坏类的对象时正确构造/销毁自身。而且,它实现了开箱即用的深层复制语义。如果您需要让调用者以只读方式访问向量,那么您可以编写一个getter,它返回对const_iterator
对象的const
或vector
引用。
答案 1 :(得分:2)
使用std :: vector是最佳选择。
如果您需要将它传递给期望指向数组的指针的函数(就像GSL经常那样),您仍然可以传递&vec[0]
...