Data hiding?

L

Lorenzo Villari

I premise I don't know C++ well but... I wondered what is this data hiding
thing... I mean, if I can look at the header (and i need it beacuse of the
class), then what's hidden?

Can someone give me an example of something hidden from the user?
 
A

Artie Gold

Lorenzo said:
I premise I don't know C++ well but... I wondered what is this data hiding
thing... I mean, if I can look at the header (and i need it beacuse of the
class), then what's hidden?

Can someone give me an example of something hidden from the user?
Perhaps `hiding' is not the best term here.

The idea of private class members is that code that *uses* objects
instantiated from a class cannot access them (directly). This means
that the class' implementation can change without needing to change
client code.

HTH,
--ag
 
L

Lorenzo Villari

Perhaps `hiding' is not the best term here.
The idea of private class members is that code that *uses* objects
instantiated from a class cannot access them (directly). This means
that the class' implementation can change without needing to change
client code.
So this means I can see it but cannot use it? How useful is this?
Oh... maybe you meant those function can be used only by a particular class?
Is this like declaring static a function?
 
P

Perry St-Germain

But wait a minute...

Lets try an example.

class myclass {
private:
int x;
mytype y;
public:
myclass(...);
};

Notice variable 'y', it's private and users of the class can't use it so we
say it is "hidden" or "encapsulated", but wait ... they will still have to
define it. What if the definition of 'mytype' requires a whole bunch of
special stuff located in a bunch of include files, the user is stuck to have
all those definitions in his name space. Then, what if there is a change in
one of those files, the user code won't have to be changed but it will have
to be recompiled.

To me this is C++ 's greatest flaw. I know there are all sorts of work
arounds but that makes things more complicated and messy. Interesting that
Lorenzo who "don't know C++ well " picked up on it right away.

Perry.
 
A

Artie Gold

Lorenzo said:
So this means I can see it but cannot use it? How useful is this?

Now there's an interesting question! ;-)
Actually, a reason that private (as well as protected) members are
`visible' (as in `you can see them in source code') is so client
code can determine the size of an object instantiated from a class.
Oh... maybe you meant those function can be used only by a particular class?

Correct. Member functions of a class -- and friends -- can use
private members of that class; general client code cannot.
Is this like declaring static a function?
It's a similar concept.

A much better explanation of all this would be found in a good book
about C++. See http://www.accu.org for suggestions.

HTH,
--ag
 
G

Gianni Mariani

Lorenzo said:
I premise I don't know C++ well but... I wondered what is this data hiding
thing... I mean, if I can look at the header (and i need it beacuse of the
class), then what's hidden?

Can someone give me an example of something hidden from the user?

The PIMPL idiom:

http://c2.com/cgi/wiki?PimplIdiom

The "fast pimpl" idiom:

http://www.gotw.ca/gotw/028.htm

and good old pure abstract classes:

This is where there is an "interface header" file (in this case
"library.h") - this file contains an "interface" description.
Specifics of the implementation are undefined. Also, there exists an
"implemnetation" file (in this case library.cpp) and this is where you
place class descriptions that "implement" the desired behaviour, and
finally there esists the "application" that uses the interface.

In this scenario (for want of a better demo) I define an array interface
"ArrayInterface" that has NO data members. The methods are virtual and
so the application has no description of the data inside the
implementation objects.

In this case I implement a really nasty hack of latent copying from the
reference WHICH IS WRONG because the assumptions are very excessive and
easily broken.

Anyhow - here is "data hiding" - this is used in real life even in C.

i.e.
// interface (library.h file)
//
class ArrayInterface
{
public:

virtual ~ArrayInterface() {}
virtual double & operator[]( int i ) = 0;
};

ArrayInterface * Factory( const char * type );

// implementation - library.cpp file

#include <vector>
#include <string>

//
// really sick - I know - it's an array that looks
// like doubles but is really a float - MEGGA nasty
// hackola - demonstration purposes only, don't try
// this at home.
//
class FloatArray : public ArrayInterface
{


std::vector<float> array;

double temp;
int temp_index;

friend ArrayInterface * Factory( const char * type );

FloatArray()
: temp_index( -1 )
{
}

void fixtemp()
{
if ( temp_index != -1 )
{
array[ temp_index ] = temp;
temp_index = -1;
}
}

double & operator[]( int i )
{
fixtemp();

if ( array.size() <= i )
{
array.resize( i + 1 );
}

temp = array;
temp_index = i;

return temp;
}
};

class DoubleArray : public ArrayInterface
{

friend ArrayInterface * Factory( const char * type );

std::vector<double> array;

double & operator[]( int i )
{
if ( array.size() <= i )
{
array.resize( i + 1 );
}

return array;
}
};



ArrayInterface * Factory( const char * type )
{
if ( std::string( "float" ) == type )
{
return new FloatArray();
}
else
{
return new DoubleArray();
}
}

#include <iostream>

void FuncThatWorksWithArray( ArrayInterface & an_array )
{
std::cout << "an_array[ 30 ] = " << an_array[ 30 ] << "\n";
std::cout << "an_array[ 20 ] = " << an_array[ 20 ] << "\n";

}

int main()
{

ArrayInterface & floater = * Factory( "float" );

ArrayInterface & doubler = * Factory( "double" );


floater[ 30 ] = 1.3;

std::cout << "floater[ 30 ] = " << floater[ 30 ] << "\n";

doubler[ 20 ] = floater[ 30 ];

std::cout << "doubler[ 20 ] = " << doubler[ 20 ] << "\n";

std::cout << "Doing floater\n";
FuncThatWorksWithArray( floater );
std::cout << "Doing doubler\n";
FuncThatWorksWithArray( doubler );
}
 
C

Cy Edmunds

Lorenzo Villari said:
I premise I don't know C++ well but... I wondered what is this data hiding
thing... I mean, if I can look at the header (and i need it beacuse of the
class), then what's hidden?

Can someone give me an example of something hidden from the user?

The point of data hiding is not to keep you from seeing it. If you're smart
you won't look anyway. The implementation should not concern you -- only the
interface. Any assumptions you make based on what you see in the
implementation just make your own code less maintainable.

If any data items in a class were not visible to the compiler, it could not
allocate memory correctly. So we do the best we can by declaring all data in
a class to be private to prevent the client from using the implementation
directly. In this sense it is (sort of) "hidden".

Google for PImpl (pointer to implementation) for a pattern related to this
issue.
 
J

Jon Bell

So this means I can see it but cannot use it? How useful is this?

You can see local variables inside an ordinary function, but you cannot
use them directly inside other functions. How useful is this?

:)
 
L

Lorenzo Villari

The point of data hiding is not to keep you from seeing it. If you're
smart you won't look anyway. The implementation should not concern you --
only
Please explain "If you're smart you won't look anyway"...
interface. Any assumptions you make based on what you see in the
implementation just make your own code less maintainable. Why?

If any data items in a class were not visible to the compiler, it could
not allocate memory correctly. So we do the best we can by declaring all
Then is "this" pointer visible? and the compiler knows anyway you refer to a
variable of a class... without "this" being present

Anyway... thank you all for your answers... I'm will think about it...
and come with new questions!
 
R

Rolf Magnus

Lorenzo said:
only
Please explain "If you're smart you won't look anyway"...

You're supposed to use the interface of a class and not care about how
it's implemented at all, so you shouldn't care about private members.

If the implementation changes, your code would have to change too. But
if a class "hides" its implementation details, and you only use the
public interface, that implementation can change without you needing to
change the code that uses it. A simple example:

class Foo
{
public:
Foo(double lengthInCM)
: centimeters_(lenghtInCM),
inch_(lengthInCM * cm_to_inch)

double centimeters() { return centimeters_; }
double inch() { return inch_; }

private:
static const double cm_to_inch = 0.394;

double centimeters_;
double inch_;
};

Notice how you cannot access the member variables centimeters_ and inch_
directly, but only through member functions. Now if the maintainer of
that class decides that it's better to calculate the lenghts
dynamically, he might change your class to:

class Foo
{
public:
Foo(double lengthInCM)
: centimeters_(lenghtInCM)

double centimeters() { return centimeters_; }
double inch() { return centimeters_ * cm_to_inch; }

private:
static const double cm_to_inch = 0.394;

double centimeters_;
};


Now there is no member variable inch_ anymore, but it doesn't matter,
since the interface didn't change, and the user code will work without
a change.
Then is "this" pointer visible?

I don't know what you mean. The "this" pointer is just a pointer to the
current object. It only exists in non-static member function of the
object's class.
and the compiler knows anyway you refer to a variable of a class...
without "this" being present

Foo f;
Foo* p = &f;

now p points to the object f. Within member functions of class Foo, you
can can get the same pointer under the name "this". There is no
difference between the "this" pointer and any other pointer to the
object.
 
G

Gavin Deane

Lorenzo Villari said:
Please explain "If you're smart you won't look anyway"...

The very next sentence answers that:

Client code, ie code that _uses_ a class, should know nothing about
how that class works internally. Otherwise, if the internals of the
class change, the client code may no longer work. Which would be a
maintenance problem.

If the client code makes no assumptions about _how_ the class works,
then the internals can change as often and as much as necessary. As
long as the class interface stays the same, the client code will still
work.

This can be achieved through information hiding (making data members
private) and through you taking no interest in how member functions
are implemented when you use a class.
Then is "this" pointer visible? and the compiler knows anyway you refer to a
variable of a class... without "this" being present

I think you have two issues confused.

The "this" pointer is only used _inside_ non-static member functions
of a class. The code inside a member function can (and probably does)
use private members of its class. But client code that _calls_ the
member function should not know anything about _how_ the member
function does its job.

The point about the compiler allocating memoroy is this. Suppose we
have

// This class defintion could equally well be in a header I included.
class foo
{
public:
int bar();
private:
void private_helper_function();
int private_data;
};

int main()
{
foo a_foo; // Must allocate memory for a_foo.

// some client code that uses a_foo.
int x = a_foo.bar();

return 0;
}

To use class foo, my main function has to be able to see the class
definition for foo, including the private section
(private_helper_function and private_data). But my code can only
actually use the public interface (in this case, just the member
function "bar"). As the programmer, I do not need to look at the
implementation of bar to be able to use the function.

Private members of a class should not concern me when I'm using the
class. So you could argue that having the private members included in
the class defintion my code sees goes against information hiding.

But when I write foo a_foo; the compiler needs to know how much memory
to allocate for the object. The only way the compiler can know that is
to know everything about the class, particularly what data members
(public or private) it contains.

It might be nice from an information hiding point of view if my code
only needed to see the public part of the class definition. But
without knowing that class foo has one int member and no other member
data, the compiler would have no way of knowing how much memory to
allocate when I write foo a_foo;
 
G

Gary

Perry St-Germain said:
But wait a minute...

Lets try an example.

class myclass {
private:
int x;
mytype y;
public:
myclass(...);
};

Notice variable 'y', it's private and users of the class can't use it so we
say it is "hidden" or "encapsulated", but wait ... they will still have to
define it. What if the definition of 'mytype' requires a whole bunch of
special stuff located in a bunch of include files, the user is stuck to have
all those definitions in his name space. Then, what if there is a change in
one of those files, the user code won't have to be changed but it will have
to be recompiled.

To me this is C++ 's greatest flaw. I know there are all sorts of work
arounds but that makes things more complicated and messy. Interesting that
Lorenzo who "don't know C++ well " picked up on it right away.

Two things:
1. Please note that "hidden" does not mean the same things as
"encapsulated."

2. Data hiding don't just mean that the user of the class cannot
access the data directly. This misconception grows out of the way the
language is taught with "simple" examples that don't show the whole
story. While it is true a user can't directly access the data if the
access is private, there is more. Suppose it is desired to encode the
data. An account number, for example, may be changed in such a way
that the stored data looks nothing like the account number. The
functions that do the encoding and decoding (usually something like
getAccout() and setAccount()) are public. The user calls the public
interface, passing it an id and providing or getting back an account
number. The way the account number is coded/decoded is completely
hidden from the user since the class source code is already compiled
and stored in an object file. If the data is written to a file (for
example) it is encoded there.
This is true data hiding. A second use for data hiding is to code the
functions that set/get the data to ask for the caller's identiy and
some proof (user id and password) and allow or disallow use of the
data based on who is trying to use it. In other words, data hiding
allows security measures concerning that data's use.

Back to point 1. The keeping together of the public functions that
manipulate the private data of the class, requiring that you have both
parts, is the essence of 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,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top