Private vs. Public data members

Hi everyone,

I am a beginner in C++ and in programming but I have a general question to experienced C++ programmers. I would really appreciate to get your opinion on a few considerations.

It seems that there are more or less strict rules about whether to keep data members private or public. I was told that the data should be stricly private in order to protect it from misbeheaving users and provide public functions to access and modify it. I understand why, I see the risks of allowing free access to a class' data. Although, from my very poor experience in programming, I noticed that there are a bunch of ways in which data needs to be accessed and/or modified through non-member functions and other classes, and sometimes the quantity of data represented in a class is large, and providing ways for accessing every part of it seems like an absurd task and a waste of time, since we know that the main purpose of the data is to be changed.

So here are basically my questions: isn't it as risky and error prone to give access to data through functions than through immediate access to the data member itself? Why do we do it? Isn't it much more logical and economical in code to simply access the data member as public?


Thanks
Typically, it is good practice to give as little access as possible, especially if you're just going to let others use your code.
The person using your class may know how to use a member, but they could inadvertently do something invalid with it.

If you want to allow access to see the value of something but not modify it, you can use a 'getter'

If you want to allow access to set the value of something but have control over how it is modified, you can use a 'setter'

Both of those are with member functions.
Even the standard library makes use of these, like doing string.length(), instead of allowing direct modification of that variable, since doing so in the wrong context could have quite negative results.
Every API/library I've used has used setter/getter methods in some form to allow access/modification of data in a controlled way.

1
2
3
4
5
6
7
8
9
10
11
12
class MyClass
{
public:
  MyClass();
  ~MyClass();

  int getInt();
  void setInt(int value);  

private:
  int myInt;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "MyClass.h"
MyClass::MyClass()
{
  ...
}

MyClass::~MyClass()
{
  ...
}

void MyClass::setInt(int value)
{
  myInt = value;
}

int MyClass::getInt()
{
  return myInt;
}


If you want to make it nicer, use const correctness
MyClass.h
1
2
3
4
...
void setInt(const int &value);
int getInt() const;
...


MyClass.cpp
1
2
3
4
5
6
7
8
9
10
...
void MyClass::setInt(const int &value)
{
  myInt = value;
}

int MyClass::getInt() const
{
  return myInt;
}
There is interface and there is implementation.
The public interface determines how a type can be used.
The implementation makes the use requests to actually do something.
Having both as separate entities decreases coupling. Dependencies.

We can overhaul the internal private implementation completely without forcing the user to do anything to their code, if the interface can be kept the same.

If you do have a humongously huge and complex class, then start to ask whether the overall design is optimal.
Great, thank you for the answer and your time!

Now what if I have a BOOK class for example with loads of data that keeps growing as I think about it (author, ISBN, number of pages, copyright date etc etc...). It seems like my class would have kind of a messy interface if I added a setter and a getter to each data member, wouldn't it? I'm asking it from a completely ignorant point of view, since I have never seen a real life class in a real program's code and have no idea what should a real life class look like and how long can it be...
Objects are not simply collections of data. The idea is that they communicate to perform tasks. A car might start an engine, then it would crash against a wall and kill its driver.
¿So what problem are you trying to solve? ¿What operations may a book do?
¿Will the author of a book change? ¿Why do you need to know the number of pages? (¿who needs to know? ¿what would they do with that information?)


A good read http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html
See my response in your other thread about changing the STATE of an object.

If you're thinking of getters and setters for every attribute of a book, you're not thinking about what an interface to a BOOK class should look like. What are the things you do with a book?

- You create a BOOK. Your constructor should have arguments for setting all the attributes of a book. You don't want to create a default BOOK, then call setters for every attribute. If you add an attribute, you can add a new constructor with the extra attribute, theby not breaking the existing interface.

- You might want to read BOOKs from a file to populate a collection in your program. Here, you want the Read() function to read the attributes of a BOOK. You don't want to do the I/O elsewhere and call setters for every attribute. The Read() function should be the only place that knows how to populate a BOOK from a file.

- You might want to write BOOKs to a file for later retrieval. Again, you want a Write() function that is responsible for writing all the attributes a a BOOK to a file. You don't want to call a bunch of getters and do the I/O elsewhere in your program.

- You might want an Edit() function that can change attributes of a BOOK. Again, you want your implementation of Edit to be responsible for updating the attributes of a BOOK. You don't want to be calling a bunch of getters and setters to do this.

- You might want to print out the attributes of a BOOK. Again, you want a single function to do this. You don't want to call a bunch of getters in order to print out the attributes of a BOOK.

So now we've defined a constructor, Read(), Write(), Edit(), and Print(). All without needing getters or setters. In the process, we've hidden the attributes of a BOOK. YOu can freely add attributes without breaking the interfaces to the class.



Wow... It seems so simple that I can't imagine I didn't see it that way. I guess simplicity is something you learn with time and practice.

Thank you all very much for your answers, I appreciate it a lot.
Topic archived. No new replies allowed.