Ideal way to return a member array

D

D. Susman

Hi,

What might the best way be to return a member variable array? (Except
using std::vector )

class A
{
public:

// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}

// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}

private:
int arr[5];
}
 
I

Ivan Vecerina

: What might the best way be to return a member variable array? (Except
: using std::vector )
:
: class A
: {
: public:
:
: // one possible way; but size info is lost
: const int* const getArrAsPtr()
: {
: return arr;
: }
:
: // Copy arr content into clientSuppliedBuffer.
: // What if client supplies int clientSuppliedBuffer[0] ?
: void getArr( int clientSuppliedBuffer[4] )
: {
: }
:
: private:
: int arr[5];
: }

If the array has a fixed size (known at compile time),
a good solution can be to return (by value, by ref, or
by const-ref) a struct that contains the array.
struct A_data { int arr[5]; };
See also http://www.boost.org/doc/html/boost/array.html,
and note that such an array<T,N> template will be part of
the standard library in C++0x.

If the size of the array varies, std::vector is a solution
if it is ok to return a copy of the contained array.
To avoid copying the data, a solution might be to return
a pair of iterators(or pointers), or like most standard
library containers, provide a begin() and an end() function
to access the iterators/pointers that delimit the range.


I hope this helps,
Ivan
 
E

Erik Wikström

Hi,

What might the best way be to return a member variable array? (Except
using std::vector )

class A
{
public:

// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}

// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}

private:
int arr[5];
}

There is no ideal way of doing this, but there are some less bad, what
you want to do is to return both a pointer to the array and the size
which means you need to use reference arguments. I would probably go
with returning the size and setting an argument to point to the array:

size_t getArray(int*& arr)
{
arr = new int[4];
for (size_t i = 0; i < 4; ++i)
arr = i;
return 4;
}


int main()
{
int* arr;
size_t size = getArray(arr);

for (size_t i = 0; i < size; ++i)
std::cout << arr << "\n";
}
 
K

Kai-Uwe Bux

D. Susman said:
Hi,

What might the best way be to return a member variable array? (Except
using std::vector )

class A
{
public:

// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}

// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}

private:
int arr[5];
}

Why not return a range:

int* arr_begin ( void ) const {
return ( &arr[0] );
}

int* arr_end ( void ) const {
return ( &arr[0] + size );
}


Best

Kai-Uwe Bux
 
D

D. Susman

D. Susman said:
What might the best way be to return a member variable array? (Except
using std::vector )
class A
{
public:
// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}
// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}
private:
int arr[5];
}

Why not return a range:

int* arr_begin ( void ) const {
return ( &arr[0] );
}

int* arr_end ( void ) const {
return ( &arr[0] + size );
}

Best

Kai-Uwe Bux

Thanks to you all. What if I wanted to do the same thing for a 2D
array?
 
D

D. Susman

D. Susman said:
What might the best way be to return a member variable array? (Except
using std::vector )
class A
{
public:
// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}
// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}
private:
int arr[5];
}

Why not return a range:

int* arr_begin ( void ) const {
return ( &arr[0] );
}

int* arr_end ( void ) const {
return ( &arr[0] + size );
}

Best

Kai-Uwe Bux

Thanks to you all. What if I wanted to do the same thing for a 2D
array?
 
E

Erik Wikström

D. Susman said:
What might the best way be to return a member variable array? (Except
using std::vector )
class A
{
public:
// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}
// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}
private:
int arr[5];
}

Why not return a range:

int* arr_begin ( void ) const {
return ( &arr[0] );
}

int* arr_end ( void ) const {
return ( &arr[0] + size );
}

Best

Kai-Uwe Bux

Thanks to you all. What if I wanted to do the same thing for a 2D
array?

Wrap it in a struct that contains the array (or pointer to it) along
with the dimensions. Seriously, you should not be playing with raw
arrays, it is usually a sign of bad design.
 
D

dave_mikesell

Hi,

What might the best way be to return a member variable array? (Except
using std::vector )

<snip>

Don't return it? Create a member function that operates on arr the
way the caller intends to, especially if the caller later calls a
setter to update arr.
 
J

Jeff Schwab

<snip>

Don't return it? Create a member function that operates on arr the
way the caller intends to, especially if the caller later calls a
setter to update arr.

s/arr/output iterator/g;
 
D

dave_mikesell

s/arr/output iterator/g;

Maybe, but it's impossible to tell from the trivial code whether or
not clients should truly have knowledge of the implementation (an
array of 5 ints in this case). In general, I prefer to keep my
private data hidden from view completely.
 
J

Jeff Schwab

Maybe, but it's impossible to tell from the trivial code whether or
not clients should truly have knowledge of the implementation (an
array of 5 ints in this case).

You are correct, but it's hard to see this as a case where less
encapsulation would be better.
In general, I prefer to keep my
private data hidden from view completely.

Agreed. With the iterator-based approach, the client need never know
anything about any private data.
 
S

Sjouke Burry

Maybe, but it's impossible to tell from the trivial code whether or
not clients should truly have knowledge of the implementation (an
array of 5 ints in this case). In general, I prefer to keep my
private data hidden from view completely.
Then dont expose yourself in public.....
 
A

Andrey Tarasevich

D. Susman said:
Hi,

What might the best way be to return a member variable array? (Except
using std::vector )

class A
{
public:

// one possible way; but size info is lost
const int* const getArrAsPtr()
{
return arr;
}

// Copy arr content into clientSuppliedBuffer.
// What if client supplies int clientSuppliedBuffer[0] ?
void getArr( int clientSuppliedBuffer[4] )
{
}

private:
int arr[5];
}

Declare 'getArr' as

void getArr( int (&clientSuppliedBuffer)[4] )

That way the type checking will not let you to pass an array of any size other
than 4.
 
D

dave_mikesell

You are correct, but it's hard to see this as a case where less
encapsulation would be better.

How can you tell with a toy example? I can envision examples where
iterators would be appropriate (like for a container), where raw
arrays would be appropriate (like for a 3D vector returning
coordinates to be rendered) and for complete encapsulation. The
example provided didn't give enough detail to determine which course
to take, so I defaulted to protecting encapsulation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top