Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 确保常量指针成员变量的常量_C++_Pointers_Compiler Errors_Constants - Fatal编程技术网

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.
    }
// ...
};