1

我对 C++ 中 Class 的私有成员有疑问:

我有一个这样定义的类:

class Hello
{
   private:
      int a[2][2] = {{1,1},{2,2}};
   public:
      int* getA();
} hello;

a是一个数组,它是类 hello 的私有成员,它被保护不能从类外部访问,但是如果我使用getA()这样的方式返回数组 a 的地址:

int* Hello::getA()
{
   return &a[2][2];
}

并且在类之外hello使用一个变量来保持这样的地址a[2][2]

int* i = getA();

i地址a[2][2]吗?我们可以像这样修改array类的外部吗?仍然受关键字保护吗?a[2][2]private

4

3 回答 3

10

发生的情况是您返回了一个指向私有成员的指针。一旦调用者有了那个指针,他们就可以自由地修改指向的数组元素。没有保护,private也不再相关。

此外,您无法控制调用者对该指针的操作,或者他们持有该指针的时间。如果a您需要强制执行某些不变量,则不能。如果a是动态分配的并且您需要重新分配它,则不能。

这很好地说明了为什么将指针泄漏到私有成员中通常不是一个好主意。

(在这里,我假设您打算返回一个指向有效元素的指针;a[2][2]超出范围。)

如果我不想修改值,只想读取数组的值,有更好的方法吗?

在这种情况下,要么通过值返回元素,要么通过const引用返回元素(你也可以通过const指针返回它,但这会给调用者带来不必要的尴尬)。

于 2012-12-03T20:15:21.443 回答
0

据我所知,您必须为二维数组返回一个双指针。

int ** Hello::getA()
{
    &a[0][0];
}

你可以自由地做

 myHello.getA()[1][1] = value; //better use pointer just in place than storing it anywhere anyway.

顺便说一句,数组是基于 0 的索引,所以如果你声明

int a[5];

最大可寻址索引是 a[4] (你有 5 个内存位置从 0 开始而不是 1.. 所以你有 a[0],a[1],a[2],a[3],a[4] )。

无论如何,在您知道自己在做什么之前,返回原始指针并不是很好的做法。

另请注意,返回

return &a[1];// is wrong (if you have a[2])

因为如果你这样做

Hello.getA()[1];

实际上,您正在尝试访问 a[2],而 a[2] 无效,因为您最多有 a[1](a[1] 是第二个值,a[1] 再次表示第二个值第二个值是第三个值!)

..如果你很幸运,那只会给你一个分段错误。如果你不走运,你将不得不搜索和调试为什么你会在某些时候得到未定义的值。

于 2012-12-03T20:26:26.350 回答
0

发生的情况是您遇到未定义的行为,因为&a[2][2]访问了无效的索引。

除此之外,private它主要是程序员的关键字 - 它不强制执行运行时检查。

于 2012-12-03T20:16:03.213 回答