Do we have to guess the error? Or the intended behaviour?
Presumably from your "friend" declaration, you want "tempClass" to only be created and destroyed by "tempClassA".
You could clarify this using better naming (these two class names are confusingly similar):
template<typename T>
void XDELETE(T *&p)
{
delete p;
p = nullptr;
}
template<class T> class Example;
template<class T> class MostlyPrivate
{
private:
friend class Example<T>;
T * m_p;
MostlyPrivate()
:m_p(nullptr)
{
}
~MostlyPrivate()
{
XDELETE(m_p);
}
};
template<class T> class Example
{
public:
Example()
:m_a(new MostlyPrivate<T>())
{
}
~Example()
{
XDELETE(m_a);
}
private:
MostlyPrivate<T> * m_a;
};
int main()
{
Example<int> a;
return 0;
}
The compiler error (having corrected some of the more trivial errors) says:
$ g++ test.cpp -std=c++0x
test.cpp: In function ‘void XDELETE(T*&) [with T = MostlyPrivate<int>]’:
test.cpp:38:10: instantiated from ‘Example<T>::~Example() [with T = int]’
test.cpp:47:18: instantiated from here
test.cpp:23:5: error: ‘MostlyPrivate<T>::~MostlyPrivate() [with T = int]’ is private
test.cpp:4:5: error: within this context
[/quote]
Highlighting the most relevant lines:
$ g++ test.cpp -std=c++0x
test.cpp: In function ‘void XDELETE(T*&) [with T = MostlyPrivate<int>]’:
test.cpp:38:10: instantiated from ‘Example<T>::~Example() [with T = int]’
test.cpp:47:18: instantiated from here
test.cpp:23:5: error: ‘MostlyPrivate<T>::~MostlyPrivate() [with T = int]’ is private
test.cpp:4:5: error: within this context
[/quote]
Essentially, the problem is that XDELETE is trying to call a private destructor. Even though "Example" is a friend, and the call to XDELETE is coming from "Example", that does not confer friendship onto XDELETE. Note this is an interesting case of where the macro version could be considered to be "bypassing" language rules.
One solution is to add XDELETE as a friend too. Another is to consider making the destructor public - perhaps making the constructor private is enough to prevent whatever mishaps you're worried about?
The most obvious solution is to use delete, not XDELETE, because you are in a destructor and thus it would be undefined behaviour for any code to touch this pointer again anyway.