保证const指针的成员变量的const性
Ensuring constness of member variable of const pointer
为什么这段代码编译得很顺利?
class myvector
{
public:
myvector()
{
begin = new double[10];
end = begin+10;
}
~myvector()
{
delete[] begin;
}
double *begin;
double *end;
};
class VectorWorker
{
public:
VectorWorker(){}
void doWork(const myvector *v)
{
for (int i=0;i<10;i++)
v->begin[i] = i; // I don't want this to compile! I'd prefer compiler says me I can't modify v->begin
}
void doWork2(const myvector *const v) const
{
for (int i=0;i<10;i++)
v->begin[i] = i; // I don't want this to compile! I'd prefer compiler says me I can't modify v->begin
}
void doWork3(const myvector &v)
{
for (int i=0;i<10;i++)
v.begin[i] = i; // I don't want this to compile! I'd prefer compiler says me I can't modify v->begin
}
};
int main(int, char*[])
{
myvector x;
VectorWorker work;
work.doWork(&x);
work.doWork2(&x);
work.doWork3(x);
return 0;
}
我希望通过const myvector *v
到VectorWorker::doWork
方法,应该确保我在myvector
中的变量是完整的,但实际上它们被修改了。如何确保doWork
方法允许进行只读操作?
实际上我不能修改double *begin
和double *end
变量为const double *
,因为它们来自第三方库。但是,我如何确保它们在通过它们所属的类的实例传递时保持完整,即使通过const pointer
?
代码可在coliru: http://coliru.stacked-crooked.com/a/bb43fbebebdb5872
使用accessors:
class myvector
{
public:
//previous code
const double* get_begin() const { return begin; }
const double* get_end() const { return end; }
double* get_begin() { return begin; }
double* get_end() { return begin; }
private:
double *begin;
double *end;
};
所以不能使用double ptr。如果你真的想让它"正常工作",你可以创建一个自定义的DoublePtr类型:
class DoublePtr
{
public:
DoublePtr() { _ptr = 0; }
DoublePtr(double* ptr) { _ptr = ptr; }
//index operators provide lookups
double& operator[](int pos) {
return _ptr[pos];
}
const double& operator[](int pos) const {
return _ptr[pos];
}
//casts for backward compatibility
operator double*() {
return _ptr;
}
operator const double*() const {
return _ptr;
}
private:
double* _ptr;
};
class myvector
{
public:
myvector()
{
buffer = new double[10];
begin = DoublePtr(buffer);
end = DoublePtr(buffer+10);
}
~myvector()
{
delete[] begin;
}
DoublePtr begin;
DoublePtr end;
private:
double* buffer;
};
那么VectorWorker代码根本不需要修改。
说了这么多,如果你可以使用它们,访问器似乎是一个更好的方法。
const不可传递;虽然指针本身是const类型(不能设置'begin'),但它指向的值不是const类型。
所以如果不修改myvector(你说这不是一个选项),或者只通过一个只提供const访问的包装器来访问它,你就无法获得这种行为。
这不是一个理想的解决方案-最好是修复myvector可憎(这是从哪个库来的?)。
。
class myvectorconst
{
private:
myvector* vec_;
public:
myvectorconst(myvector* vec) : vec_(vec) {}
double const* begin() const { return vec_->begin; }
};
class VectorWorker
{
public:
VectorWorker(){}
void doWork(const myvectorconst& v)
{
for (int i=0;i<10;i++)
v->begin()[i] = i; // Won't compile.
}
// ...
};
相关文章:
- 在内存不足之前,我可以声明多少个 const 变量?
- 当设置为 const 变量时使用 nullptr
- 声明与 const 变量和成员函数相同的标识符
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 编译器在传递 const 变量时返回错误:模板参数不是常量表达式
- 在成员函数之间传递const变量为数组的索引
- 为什么静态常量字符 * const 变量在为左值时可绑定到右值引用参数
- C 编译器可以执行用于返回值的命名const变量的RVO
- 如何访问一系列const变量作为const数组
- C 错误C3892:您无法分配const变量
- 是否可以在C++中推迟 const 变量的初始化,例如 Java 的"blank final"功能?
- 为什么将FMTFLAG指定两次 - 作为枚举的一部分,而另一个实例为静态const变量
- 使用非const变量代替所需的const变量(C )
- 使用const变量时,非静态数据成员的使用无效
- 定义,初始化全局const变量是安全的吗?
- const vs non-const变量一旦分配就没有变化
- 为什么设置const变量(将以相同的值存储)会导致不同的结果
- CPP中的私有静态常规成员变量与const变量
- 在避免新分配的同时,const变量的复杂初始化
- 如何通过其地址更改const变量的值