我对C ++中Class的私有成员有疑问:
我有一个像这样定义的类:
class Hello
{
private:
int a[2][2] = {{1,1},{2,2}};
public:
int* getA();
} hello;
a
是一个数组,它是类hello的私有成员,它受到保护而不能从类外部访问,但如果我使用getA()
返回数组的地址,则如下所示:
int* Hello::getA()
{
return &a[2][2];
}
并且在课程hello
之外使用变量来保存a[2][2]
的地址,如下所示:
int* i = getA();
i
的地址是a[2][2]
吗?我们可以像这样修改课外的array
吗? a[2][2]
是否仍受private
关键字保护?
答案 0 :(得分:10)
您所返回的指针是指向私有成员。一旦调用者具有该指针,他们就可以自由地修改指向的数组元素。没有保护,private
不再相关。
此外,您无法控制调用者对该指针执行的操作,或者它们持有多长时间。如果您需要执行某些a
不变量,则不能。如果a
是动态分配的,并且您需要重新分配它,则不能。
这是一个很好的证明,为什么泄漏指向私人成员通常不是一个好主意。
(这里,我假设您要返回指向有效元素的指针; a[2][2]
超出范围。)
如果我不想修改该值,只想读取数组的值,有更好的方法吗?
在这种情况下,要么通过值返回元素,要么通过const
引用返回(你也可以通过const
指针返回它,但这会使调用者不必要地尴尬)。
答案 1 :(得分:0)
当您遇到未定义的行为时会发生什么,因为&a[2][2]
会访问无效的索引。
除此之外,private
主要是程序员的关键字 - 它不会强制执行运行时检查。
答案 2 :(得分: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];
最大可寻址索引是[4] (你有5个记忆位置从0开始而不是1 ..所以你有[0],[1],a [2],[3],[4]。
无论如何返回原始指针并不是很好的练习,直到你知道你在做什么。
另请注意returnin
return &a[1];// is wrong (if you have a[2])
因为如果你这样做
Hello.getA()[1];
实际上你试图访问[2],而[2]无效,因为你有[1] (a [1]是第二个值,再次a [1]表示第二个值相对于第二个值,它是第三个值!)
..如果你很幸运,只会给你一个分段错误。如果你不幸运,你将不得不搜索和调试为什么你得到某些未定义的值。