c++ 面向对象
运算符重载
operator
创建一个重载运算符
成员函数运算符重载
// 现在我们创建一个对象
class Perjet {
public:
// 定义两个int 类型变量
int ba;
int bb;
// 设置变量的值
Perjet() {}
Perjet(int number,int number2) {
ba = number;
bb = number2;
}
// 定义重载运算符
Perjet operator+(Perjet &p) { // 成员重载
Perjet temp;
temp.ba = this->ba + p.ba;
temp.bb = this->bb + p.bb;
return temp;
}
};
调用
// 在调用的时候我们可以使用
Perjet a(1,2);
Perjet b(3,4);
Perjet c = a + b; // 重载 operator+ 除了+还以使用其他的运算符
全局函数运算符重载
Perjet operator-(Perjet &p,Perjet &b) // 全局函数重载
// 重载一个 - 号作用和成员函数重载一样
{
Perjet temp;
temp.ba = p.ba + b.ba;
temp.bb = p.bb + b.bb;
return temp;
}
调用 方法和成员函数一样
// 下面使调用这两个重载符号
cout << (a+b).ba << " | " << (a+b).bb << endl;
cout << (a-b).ba << " | " << (a-b).bb << endl;
输出
运算副重载函数发生重载
运算符重载函数,是可以发生重载的,我们再定义一个+ 号的重载
Perjet operator+(Perjet &p,int num){
Perjet temp;
temp.ba = p.ba + num;
temp.bb = p.bb + num;
return temp;
}
cout << (a+10).ba << " | " << (a+2).bb << endl;
执行结果
拷贝构造
拷贝构造
在类中创建一个拷贝构造函数实例:
class Person
{
public:
Person() {
cout << "Person 构造函数" << endl;
}
Person(const Person &p) { // 拷贝构造
// 拷贝构造
cout << "拷贝构造" << endl;
cout << p.age << endl;
age = p.age;
}
void setAge(int a) {
age = a;
}
void PAge()
{
cout << age << endl;
}
private:
int age;
};
使用
person p,b;
p(b);
友元
创建一个友元类
class pe;
class clxear {
friend class pe;
friend void max(clxear &p); // 友元 是全局函数 max可以访问 私有变量和函数
public:
int a;
private:
int b;
};
继承
在使用 c++ 的时候因为要创建很多不同的类,但是这些不同的类可能存在同样地功能
在此我们可以使用继承
首先我们创建一个类
class BaseHead { // 继承节点 配置
public:
void Print() {
cout << "hello world!" << endl;
}
};
使用继承
// 创建一个子类
class head:public BaseHead { // 子类使用父类 BaseHead 继承
// 子类也称为派生类
// 父类也称为基类
};
int main(int argc,char *argv[]) {
head p;
p.Print();
return 0;
}
继承方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSeRbFnn-1613901694047)(https://i.loli.net/2021/02/21/iu2gGv1VUtCrZkW.png)]
案例
#include<iostream>
using namespace std;
class Perjet {
public: // 公共继承
void PuPrint() {
cout << "This is my Public !" << endl;
}
private: // 私有继承
void PrPrint() {
cout << "This is my Private !" << endl;
}
protected: // 保护继承
void PoPrint() {
cout << "This is my Protected !" << endl;
}
};
class OnePerjet: public Perjet { // 共有继承
public:
OnePerjet() {
PoPrint();
PuPrint();
}
};
class TowPerjet: private Perjet { // 私有继承
public:
TowPerjet() {
PoPrint();
PuPrint();
}
};
class TherePerjet: protected Perjet { // 保护继承
public:
TherePerjet() {
PoPrint();
PuPrint();
}
};
int main(int argc,char *argv[]) {
class OnePerjet a;
class TowPerjet b;
class TherePerjet c;
a.PuPrint();
return 0;
}
注意基类中的私有内容,子类无法访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TXVr5VBk-1613901694051)(https://i.loli.net/2021/02/21/bmt1UXVCOgeQTjG.png)]
继承复用
class BasePage: public OnePerjet { // 继承基类 BasePage
public:
BasePage() {
cout << "BasePage" << endl;
PuPrint();
PoPrint();
}
};
class BasePerje :private OnePerjet{
public:
BasePerje() {
cout << "BasePerje" << endl;
PuPrint();
PoPrint();
}
};
继承基类,会把基类所有的内容继承
#include<iostream>
using namespace std;
class BasePage {
public:
int a;
BasePage() {
cout << &b << endl;
}
private:
int b;
protected:
int c;
};
class BaseOne:public BasePage {
public:
int ba;
BaseOne() {
cout << &b << endl;
ba = 1;
b = 2;
cout << ba << " | " << b << endl;
}
private:
int b;
};
int main(int argc,char *argv[]) {
BaseOne p;
BasePage c;
cout << sizeof(c) << endl;
cout << sizeof(p) << endl; // 基类中的所有内容都会继承 大小为20 编译器会自动帮你隐藏 私有内容
return 0;
}
输出结果
继承的构建顺序
class Perjet {
public:
Perjet() {
cout << "This is my Perjet" << endl;
}
~Perjet() {
cout << "This is my Perjet" << endl;
}
};
class BaseJet :public Perjet {
public:
BaseJet() {
cout << "This is my BaseJet !" << endl;
}
~BaseJet() {
cout << "This is my BaseJet !" << endl;
}
};
int main(int argc,char *argv[]) {
BaseJet p;
// 继承先构建 基类,然后在构建子类,删除类的时候,先删除子类,然后删除基类
return 0;
}
继承先构建 基类,然后在构建子类,删除类的时候,先删除子类,然后删除基类
继承基类调用
当子类与父类拥有同名的成员变量 时,子类会覆盖父类继承的成员,直接调用会使用的是子类成员成员变量
class Perjet {
public:
int M_y;
char M_S;
};
class BasePerjet:public Perjet {
public:
int M_S;
BasePerjet() {
M_y = 89;
M_S = 89;
Perjet::M_S = 'j';
}
};
int main(int argc,char *argv[]) {
BasePerjet a;
cout << a.M_y << " | " << a.M_S << endl;
cout << a.Perjet::M_y << " | " << a.Perjet::M_S << endl;
return 0;
}
我们可以使用a.Perjet::M_y
来精准调用
运行结果