access private member variables of other template classinstanciations

L

lutz.altmann

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()
{

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
 
I

Ian Collins

Hi, i've a question ;)
first, a quiet simple scenario .. a class template :

template<typename T> class test{

public:

void process(const test& arg)

Without making this a template member function, it will only work for
test said:
Is there a way to access private member variables of other template
class instanciations?
can i use the friend statement ? how ?
Consider each class instantiated from a class template as unique and ask
yourself the same question. You have to be explicit and name the friend
class.
 
S

Salt_Peter

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.
 

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,767
Messages
2,569,573
Members
45,046
Latest member
Gavizuho

Latest Threads

Top