本文介绍: 关键字:friend可以声明1,全局函数2,成员函数3,类注意友元打破c++的封装性。一般用于运算符重载作用是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。关键字operator语法返回值类型 operator+运算符形参列表函数体如:>>void operator>>(形参列表思路1、分析运算符的运算对象的个数2、分析运算符左边的运算对象是 自定对象 还是其他左边:是其他 只能全局函数实现 (必须使用友元)左边:自定义对象。
this指针
概念
特点
#include <iostream>
#include <cstring>
using namespace std;
class Stu{
private:
char name[50];
char sex[10];
int age;
public:
Stu(){}
Stu(char *n,char *s,int a):age(a)
{
strcpy(name,n);
strcpy(sex,s);
}
void test01()
{
//以下两句代码效果相同
//证明本类函数中调用本类成员默认使用this关键字
cout << this->name << endl;
cout << name << endl;
}
static void test02()
{
//报错,因为静态函数中没有this
//cout << name << endl;
}
};
int main(int argc, char *argv[])
{
Stu s("张三","男",18);
s.test01();
s.test02();
return 0;
}
使用场景
#include <iostream>
#include <cstring>
using namespace std;
class Stu{
private:
char name[50];
char sex[10];
int age;
public:
Stu(){}
Stu(char *name,char *sex,int age)
{
//当局部变量与成员变量重名,使用this区分
strcpy(this->name,name);
strcpy(this->sex,sex);
this->age = age;
}
void print_info()
{
//调用本类成员变量
cout << this->name << endl;
cout << this->sex << endl;
cout << this->age << endl;
}
void test()
{
//调用本类成员函数
this->print_info();
}
};
int main(int argc, char *argv[])
{
Stu s("张三","男",18);
s.print_info();
s.test();
return 0;
}
实例
#include <iostream>
#include <cstring>
using namespace std;
class Stu{
private:
char name[50];
char sex[10];
int age;
public:
Stu(){}
Stu(char *name,char *sex,int age)
{
strcpy(this->name,name);
strcpy(this->sex,sex);
this->age = age;
}
void print_info()
{
cout << this->name << endl;
cout << this->sex << endl;
cout << this->age << endl;
}
Stu& eat(char *foodName)
{
cout << name << "吃" << foodName << endl;
return *this;
}
};
int main(int argc, char *argv[])
{
Stu s("张三","男",18);
s.eat("凉皮").eat("肉夹馍").eat("甑糕");
return 0;
}
const修饰成员函数(了解)
特点
class Stu{
private:
char name[50];
char sex[10];
int age;
mutable int score;
public:
Stu(){}
Stu(char *name,char *sex,int age)
{
strcpy(this->name,name);
strcpy(this->sex,sex);
this->age = age;
}
void print_info()
{
cout << this->name << endl;
cout << this->sex << endl;
cout << this->age << endl;
}
Stu& eat(char *foodName)
{
cout << name << "吃" << foodName << endl;
return *this;
}
void test() const
{
//age = 10;//错误
score = 99;//正确
}
};
友元函数(重要)
概述
关键字
:friend
:friend
1,全局函数
2,成员函数
3,类
注意
:
:
全局友元函数
特点
示例
#include <iostream>
#include <cstring>
using namespace std;
class Stu{
friend void test(Stu &stu);
private:
char name[50];
char sex[10];
int age;
public:
Stu(){}
Stu(char *name,char *sex,int age)
{
strcpy(this->name,name);
strcpy(this->sex,sex);
this->age = age;
}
void print_info()
{
cout << this->name << endl;
cout << this->sex << endl;
cout << this->age << endl;
}
private:
void eat(char *foodName)
{
cout << name << "吃" << foodName << endl;
}
};
void test(Stu& stu)
{
//调用友元类的私有属性
cout << stu.name << endl;
cout << stu.sex << endl;
cout << stu.age << endl;
//调用友元类的私有函数
stu.eat("大嘴巴子");
}
int main(int argc, char *argv[])
{
Stu s("张三","男",18);
test(s);
return 0;
}
成员友元函数
特点
注意
4,实现成员函数
示例
#include <iostream>
#include <cstring>
using namespace std;
//定义B类,但是没有实现
class B;
class A{
public:
void test(B& b);
};
class B{
friend void A::test(B& b);
private:
int a;
public:
B(int a)
{
this->a = a;
}
private:
void print_B()
{
cout << "a = " << a << endl;
}
};
void A::test(B& b)
{
cout << b.a << endl;
b.print_B();
}
int main(int argc, char *argv[])
{
A a;
B b(10);
a.test(b);
return 0;
}
整个类作为友元函数
特点
步骤
2,
定义并实现
A
类
,
其中函数只定义不实现
定义并实现
A
类
,
其中函数只定义不实现
3,
实现
B
类
,
在其中声明
A
类为友元类
实现
B
类
,
在其中声明
A
类为友元类
示例
#include <iostream>
#include <cstring>
using namespace std;
//定义B类,但是没有实现
class B;
class A{
public:
void test01(B& b);
void test02(B& b);
};
class B{
friend class A;
private:
int a;
public:
B(int a)
{
this->a = a;
}
private:
void print_B()
{
cout << "a = " << a << endl;
}
};
void A::test01(B& b)
{
cout << "test01" << endl;
cout << b.a << endl;
b.print_B();
}
void A::test02(B& b)
{
cout << "test02" << endl;
cout << b.a << endl;
b.print_B();
}
int main(int argc, char *argv[])
{
A a;
B b(10);
a.test01(b);
cout << "--------------------" << endl;
a.test02(b);
return 0;
}
注意
1,
友元关系不能被继承。
友元关系不能被继承。
2,
友元关系是单向的,类
A
是类
B
的朋友,但类
B
不一定是类
A
的朋友。
友元关系是单向的,类
A
是类
B
的朋友,但类
B
不一定是类
A
的朋友。
3,
友元关系不具有传递性。类
B
是类
A
的朋友,类
C
是类
B
的朋友,但类
C
不一
友元关系不具有传递性。类
B
是类
A
的朋友,类
C
是类
B
的朋友,但类
C
不一
定是类
A
的朋友
A
的朋友
实例
说明
所以遥控器类是电视机类的友元类
#include <iostream>
#include <cstring>
using namespace std;
class TV;
class YK{
public:
void up(TV& tv);
void down(TV& tv);
};
class TV{
friend class YK;
private:
int yl;
public:
TV(){}
TV(int yl)
{
this->yl = yl;
}
};
void YK::up(TV &tv)
{
tv.yl++;
cout << "当前音量:" << tv.yl << endl;
}
void YK::down(TV &tv)
{
tv.yl--;
cout << "当前音量:" << tv.yl << endl;
}
int main(int argc, char *argv[])
{
TV tv(10);
YK yk;
yk.up(tv);
yk.up(tv);
yk.up(tv);
yk.down(tv);
yk.down(tv);
yk.down(tv);
return 0;
}
string
示例
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string str01 = "hello";
string str02 = str01;//字符串赋值
cout << str01 << endl;//字符串输出
cout << str02 << endl;
str02 = "world";
cout << str01 << endl;
cout << str02 << endl;
string str03 = str01 + str02;//字符串拼接
cout << str03 << endl;
string str04;
cin >> str04;//字符串输入
cout << str04 << endl;
string str05 = "Hi C++";
string str06 = "Hi C++";
string str07 = "Hi C";
cout << (str05 == str06) << endl;//判断字符串内容是否相同
cout << (str05 == str07) << endl;
cout << &str05 << endl;//打印str05地址
cout << &str06 << endl;//打印str06地址
return 0;
}
重载
引入
因为
string
类对运算符进行了重载
string
类对运算符进行了重载
那我们如何实现运算符的重载
概述
作用
关键字
operator
{
函数体
}
如:
>>
{
}
思路
#include <iostream>
#include <cstring>
using namespace std;
class Data{
public:
int x,y,z;
Data(){}
Data(int a,int b,int c):x(a),y(b),z(c){}
};
//第一个参数为运算符左边的变量
//第二个参数为运算符右边的变量
istream& operator >>(istream& in,Data& d)
{
in >> d.x >> d.y >> d.z;
return in;
}
ostream& operator <<(ostream& out,Data& d)
{
out << "x = " << d.x << "ty = " << d.y << "tz = " << d.z << endl;
return out;
}
int main(int argc, char *argv[])
{
Data d;
cin >> d;
cout << d << endl;
return 0;
}
示例2:重载+运算符
分析
示例:全局函数重载
#include <iostream>
using namespace std;
class Data{
public:
int x,y,z;
Data(){}
Data(int a,int b,int c):x(a),y(b),z(c){}
};
//第一个参数为运算符左边的变量
//第二个参数为运算符右边的变量
Data* operator +(Data& d1,Data& d2)
{
Data *d = new Data();
d->x = d1.x + d2.x;
d->y = d1.y + d2.y;
d->z = d1.z + d2.z;
return d;
}
int main(int argc, char *argv[])
{
Data d1(1,2,3);
Data d2(1,2,3);
Data* d3 = d1 + d2;
cout << d3->x << d3->y << d3->z << endl;
return 0;
}
示例
2:
成员函数重载
+
运算符
2:
成员函数重载
+
运算符
#include <iostream>
using namespace std;
class Data{
public:
int x,y,z;
Data(){}
Data(int a,int b,int c):x(a),y(b),z(c){}
//调用该函数的对象为运算符左边的变量
//参数为运算符右边的变量
Data* operator +(Data& d2)
{
Data *d = new Data();
d->x = this->x + d2.x;
d->y = this->y + d2.y;
d->z = this->z + d2.z;
return d;
}
};
int main(int argc, char *argv[])
{
Data d1(1,2,3);
Data d2(1,2,3);
Data* d3 = d1 + d2;
cout << d3->x << d3->y << d3->z << endl;
return 0;
}
示例3:重载==运算符
分析
示例
#include <iostream>
using namespace std;
class Data{
public:
int x,y,z;
Data(){}
Data(int a,int b,int c):x(a),y(b),z(c){}
//调用该函数的对象为运算符左边的变量
//参数为运算符右边的变量
bool operator ==(Data& d2)
{
if(this->x == d2.x && this->y == d2.y && this->z == d2.z)
{
return true;
}
else
{
return false;
}
}
};
int main(int argc, char *argv[])
{
Data d1(1,2,3);
Data d2(1,2,3);
Data d3(2,2,3);
cout << (d1 == d2) << endl;
cout << (d1 == d3) << endl;
return 0;
}
示例4:重载++运算符
注意
()(
成员函数
)
成员函数
)
数
),operator++(int)(
成员函数
)
),operator++(int)(
成员函数
)
示例
#include <iostream>
using namespace std;
class Data{
public:
int x,y,z;
Data(){}
Data(int a,int b,int c):x(a),y(b),z(c){}
Data& operator ++()//++前置
{
++x;
++y;
++z;
return *this;
}
Data operator ++(int)//++后置
{
Data old = *this;//记录旧值
++x;
++y;
++z;
return old;//返回旧值
}
};
ostream& operator <<(ostream& out,Data& d)
{
out << d.x << d.y << d.z << endl;
return out;
}
int main(int argc, char *argv[])
{
Data d1(1,2,3);
++d1;
cout << d1;
Data d2(1,2,3);
Data d3 = d2++;
cout << d3;
cout << d2;
return 0;
}
示例5:重载*与->
要求
重载指针运算符实现智能指针
推演
#include <iostream>
using namespace std;
class Data{
private:
int x,y,z;
public:
Data(){
cout << "无参构造函数" << endl;
}
Data(int a,int b,int c):x(a),y(b),z(c){
cout << "有参构造函数" << endl;
}
~Data()
{
cout << "析构函数" << endl;
}
};
int main(int argc, char *argv[])
{
Data *p = new Data();
return 0;
}
毁
,
那该怎么办呢
?
,
那该怎么办呢
?
解决方案如下
#include <iostream>
using namespace std;
class Data{
private:
int x,y,z;
public:
Data(){
cout << "无参构造函数" << endl;
}
Data(int a,int b,int c):x(a),y(b),z(c){
cout << "有参构造函数" << endl;
}
~Data()
{
cout << "析构函数" << endl;
}
};
class FreeData{
private:
Data* p;
public:
FreeData(){
p = NULL;
}
FreeData(Data* data){
p = data;
}
~FreeData(){
if(p != NULL)
{
delete p;
p = NULL;
}
}
};
int main(int argc, char *argv[])
{
FreeData fd(new Data(1,2,3));
return 0;
}
方案如下
#include <iostream>
using namespace std;
class Data{
private:
int x,y,z;
public:
Data(){
cout << "无参构造函数" << endl;
}
Data(int a,int b,int c):x(a),y(b),z(c){
cout << "有参构造函数" << endl;
}
~Data()
{
cout << "析构函数" << endl;
}
int getX()
{
return x;
}
};
class FreeData{
private:
Data* p;
public:
FreeData(){
p = NULL;
}
FreeData(Data* data){
p = data;
}
~FreeData(){
if(p != NULL)
{
delete p;
p = NULL;
}
}
Data& operator *()
{
return *p;
}
Data* operator ->()
{
return p;
}
};
int main(int argc, char *argv[])
{
FreeData fd(new Data(1,2,3));
cout << (*fd).getX() << endl;
cout << fd->getX() << endl;
return 0;
}
示例6:重载()
作用
对象作为函数调用
一种仿函数
示例
#include <iostream>
using namespace std;
class Data{
friend ostream& operator <<(ostream& out,Data& d);
private:
int x,y,z;
public:
Data(){
cout << "无参构造函数" << endl;
}
Data(int a,int b,int c):x(a),y(b),z(c){
cout << "有参构造函数" << endl;
}
~Data()
{
cout << "析构函数" << endl;
}
void operator ()(int a,int b,int c){
this->x += a;
this->y += b;
this->z += c;
}
};
ostream& operator <<(ostream& out,Data& d)
{
out << d.x << "t" << d.y << "t" << d.z << endl;
return out;
}
int main(int argc, char *argv[])
{
Data d(1,2,3);
d(2,5,8);
cout << d;
return 0;
}
示例7:重载=
注意
示例
#include <iostream>
using namespace std;
class Data{
friend ostream& operator <<(ostream& out,Data& d);
private:
int x,y,z;
public:
Data(){
cout << "无参构造函数" << endl;
}
Data(int a,int b,int c):x(a),y(b),z(c){
cout << "有参构造函数" << endl;
}
Data(const Data& d)
{
cout << "执行拷贝构造" << endl;
this->x = d.x;
this->y = d.y;
this->z = d.z;
}
~Data()
{
cout << "析构函数" << endl;
}
void operator =(Data& d){
cout << "执行重载=运算符的函数" << endl;
this->x = d.x;
this->y = d.y;
this->z = d.z;
}
};
ostream& operator <<(ostream& out,Data& d)
{
out << d.x << "t" << d.y << "t" << d.z << endl;
return out;
}
int main(int argc, char *argv[])
{
Data d1(1,2,3);
Data d2(3,6,9);
d1 = d2;//d1已完成初始化,执行重载的=号运算符
Data d3 = d2;//d3未完成初始化,执行拷贝构造
return 0;
}
注意:
原文地址:https://blog.csdn.net/aisheisadas/article/details/134562038
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_3500.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。