将类模板声明为类的朋友

时间:2017-08-15 18:31:31

标签: c++ oop templates

我正在尝试按照Moo和Kernig的 Accelerated C ++ (第257-257页)构建一个通用的句柄类。但是,为了调用基类的clone - 函数,我需要将通用Handle - 类设为friend Base

以下示例给出了错误:

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; }

Handle成为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;
}

2 个答案:

答案 0 :(得分:3)

问题在于Handle不是一个类;它是一个类模板。当您说friend class Handle时,它会查找名为Handle的某个类,但无法找到它。

使{em>模板的每个成员friend的正确语法是使friend声明成为模板:

class Base
{
    template <typename> friend class Handle;
    // ...
};

这就是你要求的,但我认为这不是你想要的。根据您的示例,您实际上不需要将泛型 Handle设为Base的朋友,而只需使用Base的特定朋友。这可以通过以下方式完成:

class Base
{
    friend class Handle<Base>;
    // ...
};

答案 1 :(得分:1)

friend class Handle; ///this fails

失败,因为Handle是类模板,而不是类。 Handle<Base>是一个班级。使用

friend class Handle<Base>;