模板类的友元函数、重载运算符、转换函数

#ifndef IPANDA_H
#define IPANDA_H
// 不能将模板成员函数放在单独的实现文件,
// 因为模板不是函数,不能单独编译
#include <string>
#include <iostream>
// 模板类的约束模板友元函数,因为友元函数是模板函数,
// 所以此处是友元函数的模板函数的声明,并且要在模板类之前声明,
// 所以是<typename t>,而不是<typename type>
template <typename t>int operator+(t&,t&);
template <typename type>
class panda
{
private:
 std::string _name;
 std::string name_;
 std::string _name_;
 int a;
 type k;
public:
 panda();
 panda(const std::string &name1, const std::string &name2,const std::string &name3,int,type );
 ~panda();
 const char* str(std::string _name) { return _name.c_str(); }
 // 按值传递则会创建对象副本
 friend int operator-(panda<type>& d,panda<type> &e);
 friend int operator+<>(panda<type>&, panda<type>&);
 operator int(); // 转换函数没有返回类型,没有参数
 panda<type>& operator=(panda<type>& );
 template<typename T> friend std::ostream& operator <<(std::ostream&,panda<T>&);
 template<typename TT>friend void show(TT&);
};
template <typename type>
panda<type>::panda()
{
 _name = "a";
 name_ = "b";
 _name_ = "c";
 a = 2;
}

template <typename type>
panda<type>::panda(const std::string& name1, const std::string& name2, const std::string& name3, int b, type K)
{
 _name_ = name2;
 _name = name1;
 name_ = name3;
 a = b;
 k = K;
}

template<typename type>
panda<type>::~panda()
{
 std::cout << "the destructor is called" << std::endl;
 std::cout << std::endl;
}

// 模板类也可以有友元函数,分为三类。
// 第一类:模板类的非模板友元函数
int operator-(panda<double>& d, panda<double>& e)
{             
 return d.a - e.a;
}

// 第二类:模板类的约束模板友元函数,友元函数是模板函数
// 此处是模板友元函数的实例化,因此要与模板函数的声明保持一致
template<typename t>
int operator+(t& d, t&e)
{
 return d.a + e.a;
}

template <typename type>
panda<type>::operator int()
{
 return (*this).a;
}

template <typename type>
//目的是说明panda是一个类模板,没有此说明,则panda<type>会报错
panda<type>& panda<type>::operator =(panda<type>& z)
{                    // panda<type>目的是说明panda类有一个type类型
 (*this).a = z.a;
 this->_name = z._name;
 this->name_ = z.name_;
 this->_name_ = z._name_;
 this->k = z.k;
 return *this;
}

//template<typename T> std::ostream& operator<<(std::ostream& os,T&c)
// 此种定义编译出错,
// 推测:原因是编译器直接根据第一个形参std::ostream& os进行模板函数实例化。

//template<typename T> std::ostream& operator<<(T& c, std::ostream& os)
//// 函数调用需形如:love<<cout .
//{
// using std::endl;
// os << c._name << endl;
// os << c.name_ << endl;
// os << c._name_ << endl;
// os << c.a << endl;
// return os;
//}

// 第三类:模板类的非约束模板友元函数
//template <typename T> std::ostream& operator<<(std::ostream& os,T&c) 为什么会编译出错?(show()函数)
template <typename T> std::ostream& operator<<(std::ostream& os,panda<T>&c)
{
 using std::endl;
 os << c._name << endl;
 os << c.name_ << endl;
 os << c._name_ << endl;
 os << c.a << endl;
 return os;
}

template<typename TT> void show(TT& p)
{
 std::cout << p._name<<std::endl;
}
#endif
#include <iostream>
#include "ipanda.h"
int main()
{
 using std::cin;
 using std::cout;
 using std::endl;
 //const char*不能指向string 引用,但可以指向const string 引用
 //const char*可以指向string 对象
 panda<double> panda1("A", "B", "C", 5, 5.66);
 panda<double> panda2;// 隐式调用构造函数时不需要加圆括号
 panda<double> panda3;
 cout << "重载减法运算符(模板类的非模板友元函数):\npanda1-panda2;\n";
 cout << (panda1 - panda2) << endl;
 cout << "重载加法运算符(模板类的约束模板友元函数):\npanda1+panda2;\n";
 cout << (panda1 + panda2) << endl;
 panda3=panda2=panda1;
 cout << "重载<<运算符(模板类的非约束模板友元函数):\n";
 cout << "panda1:\n"<<panda1 << endl;
 cout << "panda2\n"<<panda2 << endl;
 cout << "panda3\n"<<panda3<<endl;
 show(panda1);
 cout << int(panda2)<<endl;
 cout << panda3.operator int()<<endl;//转换函数应避免隐式转换 
 return 0;
}

在这里插入图片描述

发布了8 篇原创文章 · 获赞 0 · 访问量 338

猜你喜欢

转载自blog.csdn.net/ipanda_huanhuan/article/details/105544183
今日推荐