Mathieu Westphal
Mathieu Westphal

Reputation: 2633

Pointer to const as output parameter c++

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.

Upvotes: 0

Views: 1382

Answers (2)

anatolyg
anatolyg

Reputation: 28251

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).

Upvotes: 2

Serge Ballesta
Serge Ballesta

Reputation: 148910

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.

Upvotes: 1

Related Questions