C++ 确保常量指针成员变量的常量
为什么这段代码能顺利编译C++ 确保常量指针成员变量的常量,c++,pointers,compiler-errors,constants,C++,Pointers,Compiler Errors,Constants,为什么这段代码能顺利编译 class myvector { public: myvector() { begin = new double[10]; end = begin+10; } ~myvector() { delete[] begin; } double *begin; double *end; }; class VectorWorker { public: Vec
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;
}
类myvector
{
公众:
myvector()
{
开始=新的双精度[10];
结束=开始+10;
}
~myvector()
{
删除[]开始;
}
双*开始;
双*端;
};
类向量工作者
{
公众:
向量工作者(){}
void doWork(const myvector*v)
{
for(int i=0;ibegin[i]=i;//我不想编译这个!我希望编译器告诉我我不能修改v->begin
}
无效doWork2(常数myvector*常数v)常数
{
for(int i=0;ibegin[i]=i;//我不想编译这个!我希望编译器告诉我我不能修改v->begin
}
无效工作3(常数myvector&v)
{
对于(int i=0;i使用访问器:
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。如果您确实希望它“正常工作”,则可以创建自定义double ptr类型:
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代码根本不需要更改
话虽如此,如果您可以使用它们,那么访问器似乎是一种更好的方法。常量是不可传递的;虽然指针本身是常量(您不能设置“begin”),但它指向的值不是
因此,如果不修改myvector(您说这不是一个选项),或者只通过只提供常量访问的包装器访问myvector,您就无法获得这种行为
这并不是一个理想的解决方案——最好是修复myvector这个讨厌的问题(这是从哪个库来的?)
e、 g
类myvectorconst
{
私人:
myvector*vec;
公众:
myvectorconst(myvector*vec):vec_vec(vec){}
双常量*begin()常量{return vec->begin;}
};
类向量工作者
{
公众:
向量工作者(){}
无效工作(常数myvectorconst&v)
{
for(int i=0;ibegin()[i]=i;//将不编译。
}
// ...
};
修改v.begin
和修改v.begin
指向的内容是完全不同的事情。通常的解决方案是,如果对象是const
,则只公开一个非修改接口,但如果您无法控制myvector
的定义,那么您就无能为力。[OT]:您不遵守myvector
的规则5。
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.
}
// ...
};