简体   繁体   English

将课程模板声明为课程的朋友

[英]Declaring a class template as a friend of a class

I am trying to construct a generic handle class following Moo and Kernig's Accelerated C++ (pp. 257-257). 我正在尝试根据Moo和Kernig的Accelerated C ++ (第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 . 但是,为了调用基类的clone function,我需要使通用Handle类成为Basefriend

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

The problem is that Handle is not a class; 问题是Handle不是一个类。 it is a class template. 这是一个类模板。 When you say friend class Handle , it looks for some class named Handle , and fails to find it. 当您说friend class Handle ,它将查找名为Handle某个类,但找不到它。

The proper syntax to make every member of a template a friend is to make the friend declaration a template: 使模板的每个成员成为friend的正确语法是使friend声明成为模板:

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 . 根据您的示例,您实际上不需要使通用 Handle成为Base的朋友,而只需使使用Base的特定Handle成为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是类模板而不是类,因此失败。 Handle<Base> is a class. Handle<Base>是一个类。 Use 采用

friend class Handle<Base>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM