C++ 防止常量成员函数更改成员数组

C++ 防止常量成员函数更改成员数组,c++,constants,C++,Constants,显然,const成员函数仍然可以更改类成员指向的数据。这里有一个例子来说明我的意思: class MyClass { public: MyClass(); int getSomething() const; private: int* data; }; // ... data = new int[10];, or whatever int MyClass::getSomething() const { data[4] = 3; // this is allowed, even

显然,const成员函数仍然可以更改类成员指向的数据。这里有一个例子来说明我的意思:

class MyClass
{
public:
  MyClass();
  int getSomething() const;
private:
  int* data;
};

// ... data = new int[10];, or whatever

int MyClass::getSomething() const
{
  data[4] = 3; // this is allowed, even those the function is const
  return data[4];
}

如果这是不允许的话,我宁愿这样。我应该如何定义“数据”以便“getSomething()const”不允许更改它?(但是允许非常量函数改变它。)有什么“最佳实践”吗?也许std::vector?

没有办法做你想做的事。您的const member函数不能更改数据的值(它指向的地址),但是您已经注意到,不能更改它指向的内容。使用
std::vector
会有所帮助,因为在常量成员函数中,实际上有一个常量向量,不能调用它的任何可变函数。

const
成员函数中,
数据的类型从
int*
变为
int*const

int * const data;
这意味着,它是const成员函数中的
const
指针,而不是指针指向的数据本身。因此,您不能执行以下操作:

data = new int[100]; //error 
由于它试图更改指针本身,因此不允许更改,但允许以下操作:

data[0] = 100; //ok
因为更改内容不会更改指针<代码>数据
指向相同的内存位置

如果您使用
std::vector
,那么您可以实现您想要的。事实上,vector解决了这个问题以及内存管理问题,因此可以使用它:

class MyClass
{
public:
  MyClass();
  int getSomething() const;
private:
  std::vector<int> data;
};

MyClass::MyClass() : data(10) {}  //vector of size 10

int MyClass::getSomething() const
{
  data[4] = 3; // compilation error - this is what you wanted.
  return data[4];
}
class-MyClass
{
公众:
MyClass();
int getSomething()常量;
私人:
std::矢量数据;
};
MyClass::MyClass():数据(10){}//大小为10的向量
int MyClass::getSomething()常量
{
数据[4]=3;//编译错误-这是您想要的。
返回数据[4];
}
尽可能避免非RAII设计。RAII是解决内存管理问题的优秀解决方案。在这里,有了它,你就能实现你想要的。请阅读以下内容:


使用std::vector的原因实际上是因为您想存储int的集合,而不是int指针,所以为什么不使用它呢

这也会解决你的const'ness问题


它的工作原理是:声明一个方法常量将使所有类成员都常量化。在您的情况下,这意味着在方法范围中,您的成员
data
将成为指向int的常量指针。这意味着您可以更改int(也意味着数组成员),只要
data
指向相同的位置。使用
std::vector
,数据将成为常量
std::vector
,您只能在其上调用常量函数。所以是的,你应该使用
std::vector

是的,事实证明常量成员函数没有你想象的那么有用。@David:只有当他使用
std::vector
而不是
int*
@quasiverse:yes时,它才能变得有用。我也解释了这一点,关于如何实现他想要的。我为自己辩护,你在我的评论之后编辑了它。继续,回答+1-因为我没有选票了,我同意。我确实想存储一个int集合,我认为vector是正确的选择——不过,这段特定的代码是继承的。这不是我写的。所以我不确定是否值得把所有的int*都改成vector…不管怎样。。。遗留代码并不总是好的,您应该与管理代码的人交谈并请求更改它。