为什么这段代码能够顺利编译?
λ> parseOnly keyValuePair "k: v"
Right ("k","v")
λ> parseOnly msg "k: v\r\nk2: v2\r\n"
Right [("k","v"),("k2","v2")]
λ> parseOnly msgs "k1: v1\r\nk2: v2\r\n\r\nk3: v3\r\nk4: v4"
Right [[("k1","v1"),("k2","v2")],[("k3","v3"),("k4","v4")]]
λ> parseOnly msgs "k: v"
Right [[("k","v")]]
我希望将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 *
,我怎么能确定它们在通过它们所属类的实例时保持不变?
代码在coliru中可用:http://coliru.stacked-crooked.com/a/bb43fbebebdb5872
答案 0 :(得分:2)
使用访问者:
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;
};
答案 1 :(得分:0)
所以你不能用双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代码根本不需要更改。
说了这么多 - 如果你可以使用它们,访问者看起来似乎是一种更好的方式。
答案 2 :(得分:0)
const不是传递性的;而指针本身将是const(你可以设置'begin'),它指向的值不是。
所以你不能在不修改myvector(你说它不是一个选项)或仅通过只提供const访问的包装器访问它的情况下得到这种行为。
它不完全是一个理想的解决方案 - 最好修复myvector憎恶(这个库来自哪个?)。
e.g。
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.
}
// ...
};