Lorenzo Villari wrote:
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 "applicatio n" 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<flo at> 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[i];
temp_index = i;
return temp;
}
};
class DoubleArray : public ArrayInterface
{
friend ArrayInterface * Factory( const char * type );
std::vector<dou ble> array;
double & operator[]( int i )
{
if ( array.size() <= i )
{
array.resize( i + 1 );
}
return array[i];
}
};
ArrayInterface * Factory( const char * type )
{
if ( std::string( "float" ) == type )
{
return new FloatArray();
}
else
{
return new DoubleArray();
}
}
#include <iostream>
void FuncThatWorksWi thArray( 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";
FuncThatWorksWi thArray( floater );
std::cout << "Doing doubler\n";
FuncThatWorksWi thArray( doubler );
}