一、C++中的友元
1、C++中的访问权限
class base
{
public: //共有成员,类内,子类,类外,都可以访问
int a;
protected: //保护成员,类内,子类可以访问
int b;
private: //私有成员,类内可以访问
int c;
};
2、友元
- 作用:用于访问类中的所有成员
- 缺点:会破坏类的封装性,所以不要随便用友元
3、友元函数
语法:
friend 函数的返回值类型 函数名 (参数列表)
---------------------------------------
例子:
friend void show()//该函数就可以访问类中的所有成员
{
}
- 1、当一个函数被声明为友元函数时,该函数就不属于类中的成员函数
- 2、友元函数必须要在类内声明
- 3、友元函数可以在类内任意位置声明,与成员权限无关
例子:
#include <iostream>
using namespace std;
class base
{
public:
int a;
protected:
int b;
private:
int c;
friend void show();
};
//base类的友元函数
void show()
{
base a;
a.a = 100;
a.b = 200;
a.c = 300;
cout << a.a << endl;
cout << a.b << endl;
cout << a.c << endl;
}
int main()
{
show();
}
4、友元函数可以继承吗
class base
{
private:
int a;
//声明一个 set 友元函数
friend void set();
};
class new_base:public base
{
private:
int b;
//声明一个 set 友元函数
//friend void set();假设不重新声明友元函数就不能访问私有成员
};
void set()
{
base a;
a.a = 1000; //可以访问私有 成员
cout << a.a << endl;
new_base b;
b.b = 2000; //不可以访问 new_base 的私有成员。
}
- 1、友元函数是不可以继承的
- 2、假设需要友元函数可以访问子类的私有成员,则需要在子类中再次声明该函数为友元函数
- 3、多个类可以对应一个友元函数
- 4、一个类可以对应多个友元函数
二、友元类
作用:
- 当一个类为另一个类的友类时,则该类可以访问对方的所有数据成员
语法:
friend class 类名
----------------
例子:
friend class base;
练习: 让两个类互为友元。
#include <iostream>
using namespace std;
class base2;
class base1
{
public:
void set_b2();
int a;
protected:
int b;
private:
int c;
friend class base2;
};
class base2
{
public:
void set_b1()
{
base1 b1;
b1.a = 10;
b1.b = 20;
b1.c = 30;
}
int a;
protected:
int b;
private:
int c;
friend class base1;
};
//在base 定义后 才实现 set_base接口
void base1 :: set_b2()
{
base2 b2;
b2.a = 30;
b2.b = 20;
b2.c = 10;
}
int main()
{
}
三、运算符重载
1、作用:
- 给已知的运算符赋予新的功能。比如:两个字符串的相加 , 两个类的相加,两个结构体的相加等。
语法:
返回类型 operator 运算符号 (参数列表)
------------------------------------
例子:重载两个类相加
base operator+(base a)
{
}
2、可重载运算符:
哪些运算能重载
双目运算符 (+,-,,/, %) operator+
关系运算符 (==, !=, <, >, <=, >=)
逻辑运算符 (||, &&, !)
单目运算符 (, &, ++, --)
位运算符 (|, &, ~, ^, <<, >>)
赋值运算符 (=, +=, -=, …)
空间申请运算符 (new , delete)
其他运算符 ((), ->, [])
3、不可重载运算符:
哪些运算符不能重载
.(成员访问运算符)
.*(成员指针访问运算符)
::(域运算符)
sizeof(数据类型长度运算符)
?:(条件运算符, 三目运算符)
4、运算符重载的两种方式
类内重载方式:
base operator+(参数列表)
调用规律:
base c = a + b; - > a.operator+(b)//两者等价
特点:
a是调用者,b是参数。
在类的内部重载,友this指针
类外重载方式:
base operator+(base a, base b)
调用规律:
base c = a + b; -> operator+(a, b)//两者等价
特点:
a和b都是operator的参数,可以不用this指针
总结:
- 这两种重载运算符的方式都是一样的,用户根据自己的需要选择
四、不同运算符重载的方式
1、关系运算符:
#include <iostream>
using namespace std;
class base
{
public:
base(int a) : a(a){}
private:
int a;
friend bool operator>(base a, base b);
};
//内外重载
bool operator>(base a, base b)
{
if(a.a > b.a)
{
return true;
}
else
{
return false;
}
}
int main()
{
base b1(10);
base b2(100);
if(b1 > b2)
{
cout << "b1 > b2" << endl;
}
else
{
cout << "b1 < b2" << endl;
}
}
2、逻辑运算符
#include <iostream>
using namespace std;
class base
{
public:
base(int a) : a(a){}
bool operator&&(base a)
{
if(this->a && a.a)
{
return true;
}
else
{
return false;
}
}
private:
int a;
};
int main()
{
base a(100);
base b(10);
if(a&&b)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
3、单目运算符
#include <iostream>
using namespace std;
class base
{
public:
int a;
base(int a) : a(a){}
//++a 先自加,再用值
base operator++()
{
cout << "调用++a" << endl;
this->a++;
return *this;
}
//a++ 先用值,再自加
base operator++(int)
{
cout << "调用a++" << endl;
base tmp=*this; //保存原来的值
this->a++;
return tmp; //先返回值
}
};
int main()
{
base a(10);
base b = a++;
cout << a.a << endl;
cout << b.a << endl;
}
利用位运算符 << , >>实现输入输出的重载
1、输出运算符的重载
#include <iostream>
#include <ostream>
using namespace std;
class base
{
public:
base(int a) : a(a){}
private:
int a;
friend ostream &operator<<(ostream &out, base a);
};
//内外重载
ostream &operator<<(ostream &out, base a)
{
cout << a.a;
return out;
}
int main()
{
base a(10086);
base b(10010);
cout << a << b << endl;
}
2、输入运算符的重载
#include <iostream>
#include <istream>
using namespace std;
class base
{
public:
int a;
base(){}
base(int a) : a(a){}
};
istream & operator>>(istream &in,base &a)
{
cin >> a.a;
return in;
}
int main()
{
base a;
base b;
cin >> a >> b;
cout << a.a << endl;
cout << b.a << endl;
}
五、字符串类的使用
所有的字符串操作都可以使用string类去处理
构造函数
// 默认构造函数,创建一个空字符串
string();
// 构造函数,以指定字符重复构造字符串
string(size_type length, char ch);
// 构造函数,以C风格字符串创建字符串
string(const char *str);
// 构造函数,从C风格字符串中指定位置和长度创建字符串
string(const char *str, size_type length);
// 构造函数,从另一个字符串截取子串
string(string &str, size_type index, size_type length);