【问题标题】:Preventing a const member function from changing a member array防止 const 成员函数更改成员数组
【发布时间】:2011-09-18 06:27:34
【问题描述】:

显然,仍然允许 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 成员函数并没有你想象的那么有用。
  • @David:只有当他使用std::vector<int> 而不是int* 时,它才会有用。

标签: c++ constants


【解决方案1】:

const 成员函数中,data 的类型从int* 更改为int *const

int * const data;

这意味着,它是 const 成员函数中的 const 指针,而不是指针指向的数据本身。所以你不能做以下事情:

data = new int[100]; //error 

因为它试图改变指针本身,它是 const,因此是不允许的,但以下是允许的:

data[0] = 100; //ok

因为改变内容不会改变指针data 指向相同的内存位置。

如果你使用std::vector<int>,那么你可以实现你想要的。实际上,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];
}

尽可能避免非 RAII 设计。 RAII 是内存管理问题的卓越解决方案。在这里,有了它,您就可以实现您想要的。阅读:

【讨论】:

  • @quasiverse:是的。我也解释了那一点,关于如何实现他想要的。
  • 我为自己辩护,您在我发表评论后对其进行了编辑。继续,+1 回答。 -1,因为我没有票了。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    它也可以解决你的 const'ness 问题。

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

    【讨论】:

    • 我同意。我确实想存储一个整数集合,我认为向量是正确的选择——但是,这个特定的代码是继承的。 IE。我没写。所以我不确定是否值得将所有 int* 更改为 vector...
    • 无论如何...遗留代码并不总是好的,您应该与管理代码的人交谈并恳求更改它。
    猜你喜欢
    • 2021-05-20
    • 2011-06-04
    • 2016-08-17
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多