Re: access private member variables of other template class
instanciations
On Feb 16, 5:54 pm, lutz.altm...@mastersong.de wrote:
Hi, i've a question ;)
first, a quiet simple scenario .. a class template :
template<typename T> class test{
public:
void process(const test& arg)
{
// want to access arg.m_data (private) here !!
}
private:
T* m_data;
}
;
main()
int main()
{
test<int> obj1;
test<float> obj2;
obj.process(obj2);
}
..
Is there a way to access private member variables of other template
class instanciations?
can i use the friend statement ? how ?
Thanks,
Lutz
No, since each template would need an explicit friend statement.
The question is, if you could: would you want to?
Why not design the type with a guarenteed interface?
Lets focus on some member function get(), as an example.
[ The fact that you are storing pointers instead of data clouds the
issue.
Therefore, i'm checking for Null pointers and throwing an exception if
i attempt to access garbage. Note that the def ctor sets that ptr to
Null, not doing that would be an error in judgement. Uncomment that
statement in main's try block to see null_ptr nastyness. At least here
its being caught. ]
#include <iostream>
#include <stdexcept>
// abstract interface
template< typename I >
struct interface
{
virtual ~interface() = 0;
virtual I& get() const = 0; // pure-virtual get()
};
template< typename I >
interface< I >::~interface()
{
std::cout << "~interface()\n";
}
// conscrete type
template< typename T >
class test : public interface< T >
{
T* p_data;
public:
// def ctor sets Null ptr
test() : p_data(0) { }
test(T* p) : p_data(p) { }
// accessor
T& get() const // required !
{
if(0 == p_data) // check that p isn't Null
throw std::runtime_error("p is Null !");
return *p_data;
}
// processor, accepts any interface<>
template< typename A >
void process( const interface< A >& a )
{
// do stuff
std::cout << a.get() << std::endl;
}
};
int main()
{
try
{
int n(99);
test<int> nobj(&n);
std::cout << nobj.get() << std::endl;
test<double> dobj;
dobj.process(nobj);
// dobj.get(); // throws an exception
}
catch( std::exception& e )
{
std::cout << "Error: ";
std::cout << e.what();
std::cout << std::endl;
}
}
/*
99
99
~interface()
~interface()
*/
The member function process(...) now has a guarentee that the
arguement has a get().
And process(...) can in fact take an instance of any type as long as
its an interface<>.
Instead of complicating the relationships using friend, i'm helping
the client code too.
To see why, write another class that derives from interface<> and note
the compiler's errors if you don't provide a get(). It'll tell you
exactly what's needed.