2017-08-15 75 views
0

我想構建一個通用句柄類Moo和Kernig的加速C++(第257-257)。但是,爲了調用基類的clone-函數,我需要使通用Handle-類的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; 
} 

回答

3

的問題是,Handle不是類;它是一個類模板。當你說friend class Handle時,它會尋找一些名爲Handle的類,但無法找到它。

正確的語法,使模板的每一個部件friend是使friend聲明模板:

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

這是你問什麼,但我不認爲這是你想。根據您的示例,您實際上不需要將通用Handle作爲Base的朋友,但僅限於使用Base的特定通道。

class Base 
{ 
    friend class Handle<Base>; 
    // ... 
}; 
1
friend class Handle; ///this fails 

失敗,因爲Handle是類模板,而不是一類:這可以實現。 Handle<Base>是一類。使用

friend class Handle<Base>;