-2

So the question is:

If I have a program something like:

class Ticket
{
 private: 
    char* concertName;
 public:
    Ticket(char* name="Concert");
    char* getConcertName();
}
int main()
{
   char* test;
   Ticket t1;
   test=t1.getConcertName();
   test[1]='A';     
}
Ticket::Ticket(char* name)
{
   this->concertName=new char[strlen(Concert)+1];
   strcpy(this->concertName,name);
}
Ticket::getConcertName()
{
  return this->concertName;
}

What would the getter return? My intuition says that it returns the pointer to the first element of the memory block that I allocated earlier for concertName, and so I can change the array's values without using the setter, directly from main like I did in the example.

It works to change it, but the idea of the private area is for restricting the access from outside the object to it's attributes if a setter or a getter isn't used.

What if we had a static field like: static unsigned int* arrayI; and a static method that worked like a getter returning the value from arrayI?

User
  • 11
  • 1
  • 4

3 Answers3

1

I think you're asking for const:

Adding const to your getter will prevent the caller to modify the pointee.

#include <cstdio>
class Ticket
{
 private:
    char concertName[sizeof("Concert")];
 public:
    Ticket(const char *name = "Concert");
    const char* getConcertName() const;
};

int main()
{
   const char *test;
   Ticket t1;
   test = t1.getConcertName(); //OK with const
   //test[1]='A'; // would not compile
}
Ticket::Ticket(const char *name)
{
   snprintf(concertName, sizeof(concertName), "%s", name);
}
const char *Ticket::getConcertName() const
{
  return concertName;
}
OznOg
  • 4,440
  • 2
  • 26
  • 35
1

The usual way to prevent changes of pointer referenced memory is to use the const keyword:

const char* getConcertName() const;

The const after the member function indicates it can also be used with constant references to Ticket.

With this declaration the client is forced to use a const char* to receive the getter's result:

const char* test;
Ticket t1;
test=t1.getConcertName();

And trying to change the value will result in an appropriate compiler error message:

test[1]='A'; // <<<<<<<<<<<<<<<<< Compiler error

As a side note:
Don't manage memory allocation yourself. Instead of raw char* pointers use std::string.

user0042
  • 7,917
  • 3
  • 24
  • 39
-2

You could allocate a new char* and then return that address so that if the user changes the thing they received then it doesn't change the private field in your class.

Smit Shah
  • 111
  • 1
  • 6
  • This seems like a memory management and exception safety nightmare. I wouldn't want to have to manage an owning raw pointer every time I wanted to get a member of a class. – François Andrieux Nov 14 '17 at 18:30
  • Any solution proposed by an answer is assumed to be claimed as correct by the poster. The alternative would be that either the poster is providing a solution that he/she has no confidence in or is knowingly posting an incorrect solution. In both cases, why post at all? – François Andrieux Nov 16 '17 at 14:34
  • So you want me to get a phD before I can post on an online forum? The top answer is also forcing the user to manage a const pointer, what do you think about that – Smit Shah Nov 16 '17 at 17:28
  • No, you don't need a PhD. You just need to be confident that your answer is correct. As for the second part of your comment, while my thoughts on the other answers are irrelevant in the context of discussing your answer, I happen think that the accepted answer is correct. If you disagree or find that using `const` pointers is harmful, I encourage you to leave a comment about it on that answer. – François Andrieux Nov 16 '17 at 18:10
  • So can you elaborate on how a const pointer is better than a raw pointer? – Smit Shah Nov 16 '17 at 18:27
  • A `const` pointer is no better or worse than a non-const pointer. It's a matter of using that best one for the task at hand. But keep in mind that since `const` pointers are stricter in their use they are usually safer and should be preferred when given the choice. However, an owning raw pointer (one which points to an object for which the pointer's user must ensure destruction) is indisputably most complicated and risky to use than a non-owning pointer (for which the pointer's user only needs to ensure that the duration of that pointer's validity is sufficient). – François Andrieux Nov 16 '17 at 18:37