C++中模板类使用友元模板函…
2014-05-06 17:34
127 查看
原文地址:C++中模板类使用友元模板函数作者:浅浅的
问题始于学习数据结构,自己编写一个单链表,其中用到了重载输出运算符<<,我写的大约这样:
template <class T> class
List{
friend
std::ostream& operator
<< (std::ostream&
os,const List<T>&
slist);
//……
};用vs2008可编译,但无法链接:无法解析的外部符号……
后来上网查改为template <class T> class
List{
friend
std::ostream& operator
<<
<>(std::ostream&
os,const List<T>&
slist);
//……
};
就可以了。不知所以然,查了下《C++ Primer》才弄明白。
好了,进入正题:
在类模板中可以出现三种友元声明:
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。
要注意的是,友元函数并非成员函数,是改变了它对类成员的访问权限。
(1)没有什么好说的,如:
template<class T>
class A{
friend void fun();
//...
};
此例中fun可访问A任意类实例中的私有和保护成员
(2)
template<class T>
class A{
template<class
T>
friend void fun(T u);
//...
};
这时友元使用与类不同的模板形参,T可以是任意合法标志符,友元函数可以访问A类的任何类实例的数据,即不论A的形参是int,double或其他都可以。
(3)
template<class T>
class A{
friend void
fun<T>(T u);
//...
};
此时fun只有访问类中特定实例的数据。换句话说,此时具有相同模板实参的fun函数与A类才是友元关系。即假如调用fun时其模板实参为int,则它只具有A<int>的访问权限。当然friend
void fun<T>(T
u);中<>中的T可以是任意类型,比如int,double等
回到原问题,按(3)可改为:
template <class T> class List{
friend
std::ostream& operator
<<
<T>(std::ostream&
os,const List<T>&
slist);
//……
};
按(2)可改为:
template <class T> class List{
template
<class T>
friend
std::ostream& operator
<< (std::ostream&
os,const List<T>&
slist);
//……
};
在这里其实两者实现的最终效果一样的,因为调用输出运算符时需要访问的类实例的对象是它本身,所以形参T在第一种改法中一定匹配。
对类建立友元函数很容易。但是迁移到模板上却容易出现让人摸不着头脑的连接错误。
层次不够,不做分析,单纯介绍两种为类模板定义友元函数的方法
1 封闭型
template< typename T >
class MyClass
{
friend void function( MyClass< T > &arg )
{
}
};
要点:友元函数定义在模板体内。
2 开放型
template< typename T >
class MyClass
{
template< typename C >
friend void function( MyClass< C > &arg );
};
template< typename C >
void function( MyClass< C > &arg )
{
}
要点:模板体内要另建模板。
3 告诉编译器声明的设个是模板
#include <iostream>
using namespace std;
template < typename T >
class A
{
friend ostream &operator<< < T >( ostream &, const A< T > & );
};
template < typename T >
ostream &operator<< ( ostream &output, const A< T > &a )
{
output << "重载成功" << endl;
return output;
}
int main()
{
A< int > a;
cout << a;
}
要点:显示地在重载的运算符或者函数后面加上模板声明< T
>,告诉编译器友元函数是一个类型一致的模板。
建议:
如果希望使用函数与模板特化的类型相对应,则使用方法3(模板显示声明)
如果希望使用函数与模板特化的类型相独立,则使用方法2(二重模板)
简短的内联函数使用方法1
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/squarereal/archive/2009/09/23/4579950.aspx
问题始于学习数据结构,自己编写一个单链表,其中用到了重载输出运算符<<,我写的大约这样:
template <class T> class
List{
friend
std::ostream& operator
<< (std::ostream&
os,const List<T>&
slist);
//……
};用vs2008可编译,但无法链接:无法解析的外部符号……
后来上网查改为template <class T> class
List{
friend
std::ostream& operator
<<
<>(std::ostream&
os,const List<T>&
slist);
//……
};
就可以了。不知所以然,查了下《C++ Primer》才弄明白。
好了,进入正题:
在类模板中可以出现三种友元声明:
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。
要注意的是,友元函数并非成员函数,是改变了它对类成员的访问权限。
(1)没有什么好说的,如:
template<class T>
class A{
friend void fun();
//...
};
此例中fun可访问A任意类实例中的私有和保护成员
(2)
template<class T>
class A{
template<class
T>
friend void fun(T u);
//...
};
这时友元使用与类不同的模板形参,T可以是任意合法标志符,友元函数可以访问A类的任何类实例的数据,即不论A的形参是int,double或其他都可以。
(3)
template<class T>
class A{
friend void
fun<T>(T u);
//...
};
此时fun只有访问类中特定实例的数据。换句话说,此时具有相同模板实参的fun函数与A类才是友元关系。即假如调用fun时其模板实参为int,则它只具有A<int>的访问权限。当然friend
void fun<T>(T
u);中<>中的T可以是任意类型,比如int,double等
回到原问题,按(3)可改为:
template <class T> class List{
friend
std::ostream& operator
<<
<T>(std::ostream&
os,const List<T>&
slist);
//……
};
按(2)可改为:
template <class T> class List{
template
<class T>
friend
std::ostream& operator
<< (std::ostream&
os,const List<T>&
slist);
//……
};
在这里其实两者实现的最终效果一样的,因为调用输出运算符时需要访问的类实例的对象是它本身,所以形参T在第一种改法中一定匹配。
对类建立友元函数很容易。但是迁移到模板上却容易出现让人摸不着头脑的连接错误。
层次不够,不做分析,单纯介绍两种为类模板定义友元函数的方法
1 封闭型
template< typename T >
class MyClass
{
friend void function( MyClass< T > &arg )
{
}
};
要点:友元函数定义在模板体内。
2 开放型
template< typename T >
class MyClass
{
template< typename C >
friend void function( MyClass< C > &arg );
};
template< typename C >
void function( MyClass< C > &arg )
{
}
要点:模板体内要另建模板。
3 告诉编译器声明的设个是模板
#include <iostream>
using namespace std;
template < typename T >
class A
{
friend ostream &operator<< < T >( ostream &, const A< T > & );
};
template < typename T >
ostream &operator<< ( ostream &output, const A< T > &a )
{
output << "重载成功" << endl;
return output;
}
int main()
{
A< int > a;
cout << a;
}
要点:显示地在重载的运算符或者函数后面加上模板声明< T
>,告诉编译器友元函数是一个类型一致的模板。
建议:
如果希望使用函数与模板特化的类型相对应,则使用方法3(模板显示声明)
如果希望使用函数与模板特化的类型相独立,则使用方法2(二重模板)
简短的内联函数使用方法1
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/squarereal/archive/2009/09/23/4579950.aspx
相关文章推荐
- C++模板类使用问题
- C++模板函数和模板类的编译与使用
- C++中模板类使用友元模板函数
- C++第7周项目5 - 模板类中使用友元函数
- C++ 模板类(廿三)--template模板类使用
- C++中模板类使用友元模板函数
- 一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用
- C++中模板函数及模板类的使用(上)
- C++ - 模板类使用成员函数模板(member function template)处理隐式(implicit)转换
- C++模板类的声明、定义和使用
- C++中模板类使用友元模板函数
- 学艺不精而羞愧--论C++模板类的使用
- C++中模板函数及模板类的使用(下)
- c++模板类的简单使用
- C++中模板类使用友元模板函数
- C++中模板类使用友元模板函数
- C++单例模板类的实现和使用
- C++ 模板类使用函数指针
- C++ 使用模板类的原因
- C++模板类中使用静态成员变量(例如Singleton模式)