说我有一个看起来像这样的类(这只是一个示例):
class A {
double *ptr;
public:
A() : ptr( new double[100] ) {}
A( const A &other ) {
other.ptr[7] = 15;
}
void doNotChangeMyData() const {
ptr[43] = 14;
}
void changeMyData() {
ptr[43] = 14;
}
~A() { delete[] ptr; }
};
复制构造函数和const
函数中的doNotChangeMyData
都使之无法更改ptr
;但是,这仍然允许我修改ptr
指向的数组的内容。
是否有一种方法可以防止ptr
数组的内容仅在const
实例中被更改,而不能“小心”(或远离原始指针)?
我知道我可以做类似的事情
void doNotChangeMyData() const {
const double *const ptr = this->ptr;
ptr[43] = 14; // then this would fail to compile
}
但是我宁愿不必...
指针不传播const
。将const
添加到类型double*
会产生double* const
,在取消引用时会导致非const
左值。
相反,您可以使用std::vector
:
class A {
std::vector<double> data(100);
public:
// no explicit copy ctor or dtor
};
a std::array
:
class A {
std::array<double, 100> data{};
public:
// no explicit copy ctor or dtor
};
或内置数组(不推荐):
class A {
double data[100] {};
public:
// no explicit copy ctor or dtor
};
所有三个选项都传播const
。
如果您确实要使用指针(强烈建议不要使用),请至少使用std::unique_ptr
以避免手动内存管理。您可以使用库基本原理2 TS中的std::experimental::propagate_const
包装器:
class A {
std::experimental::propagate_const<std::unique_ptr<double[]>> ptr;
public:
A()
: ptr{new double[100] {}}
{
}
// manual copy ctor
A(const A& other)
: ptr{new double[100]}
{
std::copy_n(other.ptr.get(), 100, ptr.get());
}
// defaulted move ctor & dtor
// assignment operator, etc.
// ...
};
它尚未在标准中,但是许多编译器都支持它。当然,这种方法不如适当的容器。