The concept is thoroughly explained here, but I wanted to exemplify it a bit more to obfuscate any misunderstanding. As it will become clear, one needs to create a "preamble" with class and function definitions before specifying the class prototype and define the friend functions in a special way. Revisiting the example of StreamArrayReader, let's see how the the header file looks like:
/* * StreamArrayReader.h * * Created on: Nov 1, 2014 * Author: Pantelis Sopasakis */ #ifndef STREAMARRAYREADER_H_ #define STREAMARRAYREADER_H_ #include <iostream> using namespace std; template <typename T> class StreamArrayReader; template <typename T> void init_stream_array_reader (
StreamArrayReader<T> *o, istream * is); template <typename T> class StreamArrayReader { private: istream * in; unsigned int data_count; T *data; StreamArrayReader(); friend void init_stream_array_reader <> (
StreamArrayReader<T> *o, istream * is); public: StreamArrayReader(istream * in_stream); StreamArrayReader(char * filepath); virtual ~StreamArrayReader(); T* getData() const { return data; } unsigned int getDataCount() const { return data_count; } }; #include "StreamArrayReader.cpp" #endif /* STREAMARRAYREADER_H_ */
Notice that the function definition
template <typename T>
void init_stream_array_reader (StreamArrayReader<T> *o, istream * is);
is given before the definition of class StreamArrayReader, so we need to precede its definition:
template <typename T> class StreamArrayReader;
Notice how the friend is declared inside the class definition:
friend void init_stream_array_reader <> (
StreamArrayReader<T> *o, istream * is);
Finally, the file StreamArrayReader.cpp with the function implementations is appended inside the header file. This looks like this:
/* * StreamArrayReader.cpp * * Created on: Nov 1, 2014 * Author: Pantelis Sopasakis */ #ifndef STREAMARRAYREADER_IMPL_ #define STREAMARRAYREADER_IMPL_ #include "StreamArrayReader.h" // Other includes go here template<typename T> void init_stream_array_reader(
StreamArrayReader<T> *o, istream * is) { /* implementation goes here*/ } template<typename T> StreamArrayReader<T>::StreamArrayReader() { /* implementation goes here*/ } template<typename T> StreamArrayReader<T>::StreamArrayReader(istream * is) { /* implementation goes here*/ } template<typename T> StreamArrayReader<T>::StreamArrayReader(char * filepath) { /* implementation goes here*/ } template<typename T> StreamArrayReader<T>::~StreamArrayReader() { /* implementation goes here*/ } #endif
Very informative article.Thank you author for posting this kind of article .
ReplyDeletehttp://www.wikitechy.com/view-article/friend-function-in-cpp-with-example-program-and-explanation
Both are really good,
Cheers,
Venkat