1

How to write a get function for a private character array in the class in both .h and .cpp? I don't know whether I should use char* for the type instead or something else.

I have tried using char[] getCharArray(); but it seems not acceptable.

// in .h
class Foo{
private:
   char charArray[32];
public:
   char getCharArray(); // How to write the get function?
};


// in .cpp
char Foo::getCharArray(){
// How to write the get function in .cpp?
}

  • 1
    Get [a couple of good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) to read. They should tell you all you need to know and more. – Some programmer dude Jul 11 '19 at 03:54
  • Do you want the getter function to return a copy of the array, or provide direct access to it? If direct access, do you want that access to be read-only or read-write? Also, is this supposed to be a string or is it supposed to be an array of 32 byte values? – Nikos C. Jul 11 '19 at 03:59
  • @NikosC. I want the get function to return a character array, since I will also include a set function in the class I only want the access to be read-only. – dead_programmer Jul 11 '19 at 04:02
  • @NikosC. It is supposed to be a character array with 32 byte values. I prefer to use string because that's easier and more familiar for me but character array is required here. – dead_programmer Jul 11 '19 at 04:05
  • You can't return a raw array in C++. consider using `std::array` or `std::vector`. – eesiraed Jul 11 '19 at 05:20

4 Answers4

2

Use an std::array and return a const reference to it. This provides read-only direct access:

#include <array>

class Foo {
public:
    const std::array<char, 32>& getCharArray() const
    {
        return charArray;
    }

private:
    std::array<char, 32> charArray{}; // The '{}' zero-initializes the array.
};

If code needs a const char* pointer to the array, use the data() member function of std::array:

void printFoo(const Foo& foo)
{
    printf("%s", foo.getCharArray().data());
}
Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • returning a reference of the internal state of the object is not a good practice. – TonySalimi Jul 11 '19 at 05:53
  • @Hoodi It's a `const` reference. It can't be modified by accident. – Nikos C. Jul 11 '19 at 06:27
  • Yeah, but it is not recommended as well. Read Scott Mayer's book, i.e. Effective C++ (item #28) – TonySalimi Jul 11 '19 at 07:26
  • @Hoodi None of the things mentioned there seem to apply here. "*caller can actually modify points returned by these handles.*" This is not the case here, since we return a `const` ref. "*if you return an internal pointer to caller, it may outlive the life of your object, and the pointer will become dangling pointer*". This is also not the case here, since we are not returning a pointer. Other than that, there's nothing in the OPs question that allows us to tell whether or not exposing `charArray` is recommended or not. We don't actually know what `Foo` is supposed to be. – Nikos C. Jul 11 '19 at 08:10
  • Here is the excerpt from the book: "This is why any function that returns a handle to an internal part of the object is dangerous. It doesn’t matter whether the handle is a pointer, a reference, or an iterator. It doesn’t matter whether it’s qualified with const. It doesn’t matter whether the member function returning the handle is itself const. All that matters is that a handle is being returned, because once that’s being done, you run the risk that the handle will outlive the object it refers to." – TonySalimi Jul 11 '19 at 13:01
  • In simple words, if you store the returned reference somewhere, and the original object goes out of the scope, you will face a dangling reference, that is not good. – TonySalimi Jul 11 '19 at 15:25
  • @Hoodi Storing a reference is an explicit operation. It can't happen by accident. – Nikos C. Jul 12 '19 at 00:23
1

Since the previous answer didn't actually answer the question....

class Foo{
private:
  char charArray[32];
public:
  const char* getCharArray() const { return charArray; }
};
robthebloke
  • 9,331
  • 9
  • 12
1

For your question as asked

// in .h
class Foo
{
  private:
      char charArray[32];
  public:
     const char *getCharArray() const;
};

// in .cpp
//    include the header!
const char *Foo::getCharArray() const
{
     return charArray;
}

Bear in mind that the above returns a pointer to private data of the class Foo (rather than a copy of the array). The const qualifiers prevent the caller from (deliberately or accidentally) using the returned pointer to manipulate private data of class Foo.

However, your approach (using a raw array of char in a class) is considered a poor approach in C++. It tends to be harder to use too.

A better approach would be to use a standard container rather than a raw array.

// in .h
#include <array>     //  C++11 and later
class Foo
{
  private:
      std::array<char, 32> charArray;
  public:
     std::array<char, 32> getCharArray() const;
};

// in .cpp
//   include the header!
std::array<char, 3> Foo::getCharArray() const
{
     return charArray;
}

In this approach, the caller of Foo::getCharArray() receives a COPY of the entire array, rather than a pointer or reference to private data of class Foo. The caller can safely update the array it receives, and then later provide it back to class Foo (e.g. via a setter). Whereas, with using a pointer and a raw array, more gymnastics is needed to achieve a similar effect.

Optionally, a const reference to the std::array<char, 3> can be returned in the above, which can avoid some unnecessary copying of complete objects.

Peter
  • 35,646
  • 4
  • 32
  • 74
1

Something you can do that no one has mentioned is return a reference to the raw char array without needing std::array. I stole this idea from https://stackoverflow.com/a/34439639/10290252.

//.h file
class Foo{
private:
   char charArray[32];
public:
   char (&getCharArray())[32];
};


// .cpp file
char (&Foo::getCharArray())[32]{
   return charArray;
}

I want to stress however DO NOT DO THIS!! Nikos C gave the correct answer and you should follow their example.

QCTDev
  • 166
  • 6