06笔记 友元 类模板 运算符 输入输出流的重载

目录

文字部分:

代码部分: 

一.友元 

         一.友元函数

         二.友元类

 二.类模板

 三.运算符重载

法一:类内函数

法二:类外函数:建立友元关系;

 四.输入输出流的重载


文字部分:

// //0206
//一.友元:包括友元函数和友元类。
/*
友元函数必须在类中用关键字 friend 声明
友元函数是类外函数,但是通过firend与类建立连接
//从而能够访问类内的私有数据成员和保护成员
友元类的定义:teacher类
友元类必须写在元类的下面

一般格式为:
friend  <type> FuncName(<args>);

友元函数不是成员函数,用法也与普通的函数完全一致,
只不过它能访问类中所有的数据。
友元函数破坏了类的封装性和隐蔽性,
使得非成员函数可以访问类的私有成员。

*/


//类模板
/*
对数据的处理方式相同,但是因为数据类型不同,
如果定义不同的类,写起来会比较繁琐
所以可以用类模板来简化程序
*/
//声明一个类模板,虚拟类型名称为temp

//运算符重载:
//类内函数和类外函数,类外函数需要建立友元关系。


//输入输出流重载:
在C++中允许用户重载运算符“<<”和“>>”,实现对象的输入和输出。重载这二个运算符时,在对象所在的类中,将重载这二个运算符的函数说明该类的友元函数。

重载提取运算符的一般格式为:

friend  istream &  operater >>(istream &, ClassName &);

friend  ostream &  operater <<(ostream &, ClassName &);

代码部分: 

一.友元 

         一.友元函数

#include <iostream>
using namespace std;
class student
{
private:
    //静态数据成员 
    static string edu;
    static int cnt;//可以用来统计学生个数

    string name;
    double math;
    double chinese;

    double getaverage() { return (math + chinese) / 2; }
public:
    void setname(string name) { this->name = name; }
    void setmath(double math) { this->math = math; }
    void setchinese(double c) { this->chinese = c; }
    void setinfo(string name, double m, double c);//函数声明
    void showinfo();


    static void sing();//静态成员函数 

    student(const student&);//常引用;//复制构造函数;
    student();
    student(string, double, double);
    ~student()
    {
        cout << "~student() destructing……" << endl;
    }
    friend void showstudent(student& st);//声明友元函数
};

//静态数据的初始化
string student::edu = "BUPT";
int student::cnt = 0;

//静态函数的定义
void student::sing()
{
    cout << "hello world" << endl;
}
//函数定义
inline void student::setinfo(string name, double c, double m)
{
    this->name = name;
    this->chinese = c;
    this->math = m;
}

inline void student::showinfo()
{
    cnt++;//静态数据成员的使用
    cout << "----------" << endl;
    cout << "fuction showinfo() constructing……" << endl;
    cout << "cnt:" << cnt << endl;//静态数据的输出 
    cout << "edu:" << edu << endl;//静态数据的输出 
    cout << "name:" << this->name << endl;
    cout << "chinese:" << this->chinese << endl;
    cout << "math:" << this->math << endl;
    cout << getaverage() << endl;
    cout << "----------" << endl;
    cout << endl;
}
//复制构造函数
student::student(const student& st)
{
    this->name = st.name;
    this->math = st.math;
    this->chinese = st.chinese;
    cout << "student(const student&) constructing……" << endl;
}
//无参构造函数
student::student()
{
    cout << "student()constructing……" << endl;
    this->name = "unknown_name";
    this->chinese = 0;
    this->math = 0;
}
//有参构造函数
student::student(string name, double m, double c)
{
    cout << "student(string,double,double) constructing……" << endl;
    this->name = name;
    this->math = m;
    this->chinese = c;
}

//友元函数 
void showstudent(student& st)
{

    cout << "----------------" << endl;
    cout << "showstudent is running……" << endl;
    cout << "name:" << st.name << endl;//直接写是不可以访问的,
    //建立了友元关系才可以直接访问。 
    cout << "chinese:" << st.chinese << endl;
    cout << "math:" << st.math << endl;
    cout << "-----------------" << endl;
}
//友元函数是类外函数,但是通过friend与类建立联系,
//从而实现了类外函数访问类内私有数据成员
int main()
{
    student st[5];//对象
    string name;
    float m, c;
    for (int i = 1; i <= 3; i++)
    {
        cout << "请输入第" << i << "个同学的信息" << endl;
        cin >> name;
        cin >> m;
        cin >> c;
        st[i].setinfo(name, c, m);
    }
    cout << endl;
    for (int i = 1; i <= 3; i++)
    {
        cout << "第" << i << "个同学的信息:" << endl;
        st[i].showinfo();
    }
    cout << endl;
    for (int i = 1; i <= 3; i++)
    {
        showstudent(st[i]);
    }

    //静态成员函数的调用
    cout << endl << "静态成员函数正在显示……" << endl;
    st[0].sing();
    cout << endl;
    return 0;
}

        运行结果:

 

         二.友元类

        友元类需要在原来的元类内 声明

        格式friend class 友元类名称

#include <iostream>
using namespace std;
// //0206
//一.友元:包括友元函数和友元类。
/*
友元函数必须在类中用关键字 friend 声明

友元类的定义:teacher类
友元类必须写在元类的下面
*/
class student
{
private:
    //静态数据成员 
    static string edu;
    static int cnt;//可以用来统计学生个数

    string name;
    double math;
    double chinese;

    double getaverage() { return (math + chinese) / 2; }
public:
    void setname(string name) { this->name = name; }
    void setmath(double math) { this->math = math; }
    void setchinese(double c) { this->chinese = c; }
    void setinfo(string name, double m, double c);//函数声明
    void showinfo();


    static void sing();//静态成员函数 

    student(const student&);//常引用;//复制构造函数;
    student();
    student(string, double, double);
    ~student()
    {
        cout << "~student() destructing……" << endl;
    }
    //friend void showstudent(student& st);//声明友元函数
    friend class teacher; 
};

//静态数据的初始化
string student::edu = "BUPT";
int student::cnt = 0;

//静态函数的定义
void student::sing()
{
    cout << "hello world" << endl;
}
//函数定义
inline void student::setinfo(string name, double c, double m)
{
    this->name = name;
    this->chinese = c;
    this->math = m;
}

inline void student::showinfo()
{
    cnt++;//静态数据成员的使用
    cout << "----------" << endl;
    cout << "fuction showinfo() constructing……" << endl;
    cout << "cnt:" << cnt << endl;//静态数据的输出 
    cout << "edu:" << edu << endl;//静态数据的输出 
    cout << "name:" << this->name << endl;
    cout << "chinese:" << this->chinese << endl;
    cout << "math:" << this->math << endl;
    cout << getaverage() << endl;
    cout << "----------" << endl;
    cout << endl;
}
//复制构造函数
student::student(const student& st)
{
    this->name = st.name;
    this->math = st.math;
    this->chinese = st.chinese;
    cout << "student(const student&) constructing……" << endl;
}
//无参构造函数
student::student()
{
    cout << "student()constructing……" << endl;
    this->name = "unknown_name";
    this->chinese = 0;
    this->math = 0;
}
//有参构造函数
student::student(string name, double m, double c)
{
    cout << "student(string,double,double) constructing……" << endl;
    this->name = name;
    this->math = m;
    this->chinese = c;
}
/*
//友元函数 
void showstudent(student& st)
{
    
    cout << "----------------" << endl;
    cout << "showstudent is running……" << endl;
    cout << "name:"<<st.name << endl;//直接写是不可以访问的,
	//建立了友元关系才可以直接访问。 
    cout <<"chinese:"<< st.chinese << endl;
    cout <<"math:"<<st.math << endl;
    cout << "-----------------" << endl;
}

*/

//创建友元类:teacher类 
class teacher
{
public:
    void showstudent(student& st)
    {
        cout << "------------" << endl;
        cout << "友元类中的showstudent函数正在运行" << endl;
        cout << st.name << endl;
        cout << st.chinese << endl;
        cout << st.math << endl;
        cout << "----------------" << endl;
    }
};



int main()
{
    student sta("zhang", 88, 99);
    sta.showinfo();//调用类内函数 
    /*
    student st[10];//对象
    string name;
    float m, c;
    for (int i = 1; i <= 3; i++)
    {
        cout << "请输入第" << i << "个同学的信息" << endl;
        cin >> name;
        cin >> m;
        cin >> c;
        st[i].setinfo(name, c, m);//调用类内函数 
    }
    for (int i = 1; i <= 3; i++)
    {
        cout << "第" << i << "个同学的信息:" << endl;
        st[i].showinfo();//调用类内函数 
    }
    */
    teacher t1;
    t1.showstudent(sta);//调用友元类中的函数 
    return 0;
}

运行结果:

 

 二.类模板

//类模板
/*
对数据的处理方式相同,但是因为数据类型不同,
如果定义不同的类,写起来会比较繁琐
所以可以用类模板来简化程序
*/
//声明一个类模板,虚拟类型名称为temp

代码部分:

#include <iostream>
using namespace std;
//类模板
/*
对数据的处理方式相同,但是因为数据类型不同,
如果定义不同的类,写起来会比较繁琐
所以可以用类模板来简化程序
*/
//声明一个类模板,虚拟类型名称为temp

template <class temp>

class compare
{
public:
	compare(temp a,temp b)
	{
		this->x = a;
		this->y = b;
	}
	temp max(){ return x > y ? x : y; }
	temp min() { return x > y ? y : x; }
private:
	temp x; temp y;
};
int main()
{
	compare<int>INT(2, 3);
	cout << INT.max() << endl;//3
	cout << INT.min() << endl;//2
	compare<double>DOUBLE(2.2, 3.3);
	cout << DOUBLE.max() << endl;//3.3
	cout << DOUBLE.min() << endl;//2.2
	return 0;
}

 三.运算符重载

这里只以“+”举例,详细讲解请参考链接:

待解决的问题:

使得这行代码合法:

complex a,b,c;
c=a+b;
return c;

未重载的加号,只能用于计算C++预先定义的数据类型,而类 是用户自定义数据类型,

所以正常加号无法使用

其中加号如果没有“重载”,程序会制动报错

程序功能描述:

实现两个复数相加。

法一:类内函数

#include <iostream>
using namespace std;
class complex
{
private:
	double real, imag;
public:
	complex() { real = 0; imag = 0; }
	complex(double a, double b) { real = a; imag = b; }
	complex operator + (complex&);//类内一个参数的运算符重载
    //complex operator + (complex&,complex&);//错误:"此运算符函数的参数太多"
	void showcomplex() { cout << "(" << real << "," << imag << "i)" << endl; }

};
inline complex complex::operator+(complex& a)
//函数的返回值类型 上一级::下一级 运算符(数据类型 变量名称)
{
	complex c;
	c.real = this->real + a.real;
	c.imag = this->imag + a.imag;
	return c;
}
int main()
{
	complex a(2, 3), b(4, 5), c;
	c = a + b;
	a.showcomplex();
	b.showcomplex();
	c.showcomplex();
	return 0;
}

法二:类外函数:建立友元关系;

#include <iostream>
using namespace std;
class complex
{
private:
	double real,imag;
public:
	complex() { real = 0; imag = 0; }
	complex(double a, double b) { real = a; imag = b; }
	//complex operator + (complex&);
	void showcomplex(){ cout << "(" << real << "," << imag << "i)" << endl; }
	friend complex operator +(complex&, complex&);

};
/*
inline complex complex::operator+(complex& a)
//函数的返回值类型 上一级::下一级 运算符(数据类型 变量名称)
{
	complex c;
	c.real = this->real + a.real;
	c.imag = this->imag + a.imag;
	return c;
}
*/
//法二: 
complex operator + (complex& a, complex& b)
{
	complex c;
	c.real = a.real + b.real;
	c.imag = a.imag + b.imag;
	return c;
}
int main()
{
	complex a(2, 3), b(4, 5), c;
	c = a + b;
	a.showcomplex();
	b.showcomplex();
	c.showcomplex();
	return 0;
}



两种方法有相同的运行结果:

 四.输入输出流的重载

在C++中允许用户重载运算符“<<”和“>>”,实现对象的输入和输出。重载这二个运算符时,在对象所在的类中,将重载这二个运算符的函数说明该类的友元函数。

重载提取运算符的一般格式为:

friend  istream &  operater >>(istream &, ClassName &);

friend  ostream &  operater <<(ostream &, ClassName &);

#include <iostream>
using namespace std;
class complex
{
private:
	double real,imag;
public:
	complex() { real = 0; imag = 0; }
	complex(double a, double b) { real = a; imag = b; }
	complex operator + (complex&);
	void showcomplex(){ cout << "(" << real << "," << imag << "i)" << endl; }
	//friend complex operator +(complex&, complex&);
	friend istream& operator>>(istream&, complex&);//输入流重载的声明
	friend ostream& operator<<(ostream&, complex&);//输出流重载的声明

};
inline complex complex::operator+(complex& a)
//函数的返回值类型 上一级::下一级 运算符(数据类型 变量名称)
{
	complex c;
	c.real = this->real + a.real;
	c.imag = this->imag + a.imag;
	return c;
}
//写法2
/*
complex operator + (complex& a, complex& b)
{
	complex c;
	c.real = a.real + b.real;
	c.imag = a.imag + b.imag;
	return c;
}
*/
//istream 输入流 ostream 输出流
//输入流重载

istream& operator >>(istream &input, complex& c)
{
	cout << "请分别输入一个复数的实部和虚部:" << endl;
	input >> c.real >> c.imag;
	return input;
}
//输出流重载
ostream& operator<<(ostream& output, complex& c)
{
	output << "(" << c.real << "," << c.imag << "i)" << endl;
	return output;
}

int main()
{
	complex a, b, c;
	cin >> a >> b;
	c = a + b;
	a.showcomplex();
	b.showcomplex();
	c.showcomplex();
	cout << c;
	return 0;
}

运行结果:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山入墨雨如画

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值