I am trying to construct a generic handle class following Moo and Kernig's Accelerated C++ (pp. 257-257). However, in order to call the clone
-function of the base class I need to make the generic Handle
-class a friend
of Base
.
The example below gives me the errors:
main.cpp:30:18: error: template argument required for ‘class Handle’
friend class Handle;
^
main.cpp:30:5: error: friend declaration does not name a class or function
friend class Handle;
^
main.cpp: In instantiation of ‘Handle<T>& Handle<T>::operator=(const Handle<T>&) [with T = Base]’:
main.cpp:42:7: required from here
main.cpp:33:19: error: ‘virtual Base* Base::clone() const’ is protected
virtual Base *clone() const { return new Base; }
What is the proper notation for making Handle
a friend to Base
?
#include <iostream>
template <class T>
class Handle
{
public:
Handle() : p(0) {}
Handle &operator=(const Handle &);
~Handle() { delete p; }
Handle(T *t) : p(t) {}
private:
T *p;
};
template <class T>
Handle<T> &Handle<T>::operator=(const Handle &rhs)
{
if (&rhs != this)
{
delete p;
p = rhs.p ? rhs.p->clone() : 0;
}
return *this;
};
class Base
{
friend class Handle; ///this fails
protected:
virtual Base *clone() const { return new Base; }
private:
int a;
};
main()
{
Handle<Base> h;
h = new Base;
return 0;
}
The problem is that Handle
is not a class; it is a class template. When you say friend class Handle
, it looks for some class named Handle
, and fails to find it.
The proper syntax to make every member of a template a friend
is to make the friend
declaration a template:
class Base
{
template <typename> friend class Handle;
// ...
};
This is what you asked for, but I don't think it's what you want. Given on your example, you don't actually need to make the generic Handle
a friend of Base
, but only the specific one which uses Base
. This can be accomplished with:
class Base
{
friend class Handle<Base>;
// ...
};
friend class Handle; ///this fails
That fails since Handle
is class template, not a class. Handle<Base>
is a class. Use
friend class Handle<Base>;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.