0

I am trying to get multiple pointer in one get methods, without leaving the user the right to modify the data. Here is my implementation :

class A {
public:
   bool getAB( int** a, int** b ) const
protected :
   int * a_;
   int * b_;
}


bool getAB( int** a, int** b ) const
{
    *a = a_;
    *b = b_;
     return true;
}

But this way, user can modify, and even free the data. I could implement like two different getter wich return const int*, but i would like to know if there is a correct way to do that.

Mathieu Westphal
  • 2,537
  • 1
  • 15
  • 27
  • possible duplicate of [How do I remove code duplication between similar const and non-const member functions?](http://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func) – Cory Kramer Jan 05 '15 at 16:02
  • For getters it is trivial, but for more complicated functions, the above details how you can make `const` and non-`const` versions of functions maintainably. – Cory Kramer Jan 05 '15 at 16:02
  • I'm sorry, but it is not about const and non-const version of getter. I only want a multiple output const getter. – Mathieu Westphal Jan 05 '15 at 16:05
  • No, returning pointers to your class internals is wrong and there are no correct ways to do wrong. – n. 'pronouns' m. Jan 05 '15 at 16:40
  • are references okay ? if not, do you thing i should copy the contents of the pointers ? – Mathieu Westphal Jan 05 '15 at 17:08

2 Answers2

2

In c++, the proper way to return multiple values is by reference:

class A {
public:
   bool getAB( int*& a, int*& b ) const
   {
      a = _a;
      b = _b;
   }
protected :
   int * a_;
   int * b_;
}

(I also made the method inline to simplify the example)

If you want to disallow altering the data, return a pointer to const:

class A {
public:
   bool getAB( const int*& a, const int*& b ) const
   {
      a = _a;
      b = _b;
   }
protected :
   int * a_;
   int * b_;
}

Note that the user can still call delete (but not free) on the result of getAB; see this question for more info. If you want to disallow delete, you can replace pointers by smart pointers (e.g. std::unique_ptr).

Actually, if you want your code to be compatible with c++ exceptions, you should never hold two pointers in your class (and rarely, if ever, hold one pointer).

Community
  • 1
  • 1
anatolyg
  • 23,079
  • 7
  • 51
  • 113
  • Thx, it works. However i do not understand what is so bad about manipulating pointers. In my case, classe is handling different allocated array stored as pointers. – Mathieu Westphal Jan 05 '15 at 17:04
  • @user1416930 `std::vector` does the necessary stuff for allocating arrays. It also supports correct copying/moving of your objects (see [this question](http://stackoverflow.com/q/4172722/509868)), and exception safety. If you don't need any of these features, fine. However, `std::vector` may still be more convenient and faster than whatever you do for allocating your arrays. – anatolyg Jan 05 '15 at 17:13
  • ok, thx for explanation. maybe i've doing a bit too much of C these days. – Mathieu Westphal Jan 05 '15 at 17:16
1

You can indeed protect a little more the internal values, but it will be hard to forbid a delete. Here is the best I could do

class A {
public:
   bool getAB( const int ** const  a, const int ** const  b ) const;
   A(int * a, int *b): a_(a), b_(b) {}
protected :
   int * a_;
   int * b_;
};


bool A::getAB( const int ** const  a, const int ** const  b ) const
{
    *a = a_;
    *b = b_;
     return true;
}

int main() {
    int i=1;
    int j=2;

    A a(&i, &j);

    const int *  p1;
    const int *  p2;
    // int *  p2; error

    a.getAB(&p1, &p2);

    // *p1 = 3;  error
    // delete p1; unfortunately gives no errors

    cout << *p1 << " " << *p2 << endl;
    return 0;
}

It does require a pointer to const, but delete is unfortunately allowed. And it is not possible to pass a const pointer, because a const pointer has to be immediately initialized.

Serge Ballesta
  • 121,548
  • 10
  • 94
  • 199