返回指针的Getter上的数组访问是不好的做法?

时间:2014-04-23 06:59:00

标签: c++ c arrays pointers getter-setter

想象一下以下场景:

class A 
{
    int a[50];
    int* GetAPtr() { return a; };
};
...
A b;
if(b.GetAPtr()[22] == SOME_RANDOM_DEFINE) do_this_and_that();

这种访问被认为是不好的做法吗? b.GetAPtr()[22]

澄清我的情况:
1.在这种情况下我不能使用new / malloc,数组muste是静态的 这是为了封装使用多个阵列的旧C代码,这些代码非常方便 3.我知道返回一个指针可能会返回一个NULL指针,我们在这里不讨论这个问题

3 个答案:

答案 0 :(得分:2)

如果你真的需要这样的const表达式,你可以把它变成一个函数:

class A 
{
    int a[50];
    bool check_this_and_that() { return a[22] == SOME_RANDOM_DEFINE; };
};
...
A b;
if(b.check_this_and_that()) do_this_and_that();

魔术数字一般很糟糕,但在类逻辑中它更可原谅,外人不必看到这一点。

答案 1 :(得分:1)

是的,这是不好的做法,因为你无法知道数组有多长。您可以遵循惯用标准库方法并返回beginend指针,指向第一个和最后一个元素。

class A 
{
    int a[50];
    int* begin() { return &a[0]; };
    int* end() { return &a[50]; };
    const int* begin() const { return &a[0]; };
    const int* end() const { return &a[50]; };
    size_t size() const { return 50; } // this could be handy too
};

除了为您提供迭代元素的工具,就像在标准库容器上一样,这允许您检查指向数组元素的任何指针是否为< v.end()。例如

it* it = b.begin() + 22;
if(it < b.end() && *it == SOME_RANDOM_DEFINE) do_this_and_that();

这使得使用标准库算法变得微不足道:

A b;
// fill with increasing numbers
std::iota(b.begin(), b.end());
// sort in descending order
std::sort(s.begin(), s.end(), std::greater<int>());

// C++11 range based for loop
for (auto i : b) 
  std::cout << i << " ";
std::endl;

答案 2 :(得分:0)

GetAPtr是一种访问私有数据成员的方法。现在问问自己b.GetAPtr()[22]优于b.a[22]的优势是什么?

封装数据是维护数据成员之间和之间约束的好方法。在您的情况下,a数组与其长度50之间至少存在关联。

根据A的使用情况,您可以构建一个提供不同访问模式的界面:

class A {
   int a[50];
public:
   // low level
   int atA(unsigned i) const { return a[i]; }
   // or "mid" level
   int getA(unsigned i) const { if(i >= 50) throw OutOfRange(); return a[i]; };
   // or high level
   bool checkSomething() const { return a[22] == SOME_RANDOM_DEFINE; }
};