封装
将属性和行为作为一个整体,表现生活中的事物
将属性和行为加以权限控制
访问权限
// 公共权限 类内可以访问,类外可以访问
public:
// 保护权限 类内可以访问,类外不可以访问
protected:
// 私有权限 类内可以访问,类外不可以访问
private:
#include <iostream>
using namespace std;
long long a, b;
// class代表设计一个类,类后面紧跟着的就是类名称
class Circle
{
// 访问权限
// 公共权限
public:
// 属性
//半径
int m_r;
// 行为
//获取圆的周长
double calculate()
{
return 2*3.14*m_r;
}
};
int main()
{
//通过圆类创建具体的圆
Circle cl;
cl.m_r=10;
cout<<"calculate="<<cl.calculate()<<endl;
return 0;
}
成员属性为私有,可以自己控制读写权限
构造函数
*构造函数,没有返回值,也不写void
*函数名与类名相同
*构造函数可以有参数,因此可以发生重载
*程序在调用对象时会自动调用构造
#include <iostream>
using namespace std;
long long a, b;
class Person
{
private:
int m_L, m_W,m_H;
public:
~Person()//函数名和类名相同 在名称前加~
{
cout<<"Person 构造函数的调用"<<endl;
}//构造函数
};
//析构函数 进行清理操作
//构造和析构都是必须有的 自己不提供的话编译器会提供一个空实现的构造和析构
void test1()
{
Person p;//
}
int main()
{
test1();
return 0;
}

两种分类方式:
有参构造无参构造
普通构造拷贝构造
拷贝构造函数的调用时机

深拷贝与浅拷贝
浅拷贝:简单的复制拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作

深拷贝【指针】

#include <iostream>
using namespace std;
class Person
{
public:
int m_age;
int *m_weight;
Person(int age,int weight)
{
m_age = age;
m_weight=new int(weight);
cout << "有参" << endl;
}
Person(const Person &p)
{
cout << "person copydo" << endl;
m_age = p.m_age;
//深拷贝操作
m_weight = new int(*p.m_weight);
}
~Person()
{
if(m_weight!=NULL){
delete m_weight;
m_weight=NULL;
}
cout << "析构do" << endl;
}
};
// 调用
void test01()
{
Person(14,134);
Person p1(19,188);
Person p2(p1);
}
int main()
{
test01();
return 0;
}
析构函数
对象的初始化和清理:
初始化列表
#include <iostream>
using namespace std;
class Person
{
public:
int m_A;
int m_B;
int m_C;
Person(int a, int b, int c) : m_A(a), m_B(b), m_C(c) {}
};
int main()
{
Person p1(10, 20, 30);
cout << p1.m_A << " " << p1.m_B << ' ' << p1.m_C;
return 0;
}
类对象作为类成员
#include <iostream>
using namespace std;
class Phone
{
public:
string p_kind;
Phone(string name)
{
p_kind = name;
}
~Phone(){
cout<<"析构2"<<endl;
}
};
class Person
{
public:
string m_name;
Phone m_phone;
Person(string name, string kind) : m_name(name), m_phone(kind) {
cout<<"do"<<endl;
}
~Person(){
cout<<"析构1"<<endl;
}
};
void test01()
{
Person p("aisssky", "huawei");
cout<<p.m_phone.p_kind;
}
int main()
{
test01();
return 0;
}
静态成员

#include <iostream>
using namespace std;
class Phone
{
public:
static int m_A;
// 所有成员都共享同一份数据
private:
static int m_B;
};
int Phone ::m_A = 100; // 类外初始化操作
int Phone ::m_B=200;
void test01()
{
Phone p;
Phone p2;
p2.m_A = 200; // 结果变为200
cout << p.m_A << endl;
}
void test02()
{
// 静态成员变量 不属于某个对象上 所有成员都共享一份数据
// 因此静态成员变量有两种访问方式
Phone p3;
// 1.通过对象进行访问
cout << p3.m_A << endl;
// 2.通过类名进行访问
cout << Phone::m_A << endl;//类外访问不到私有成员
}
int main()
{
test01();
test02();
return 0;
}
静态函数只能访问静态成员
#include <iostream>
using namespace std;
class Phone
{
public:
static int m_A;
// 所有成员都共享同一份数据
static void func(){
m_A=522;
cout<<"static void do"<<endl;
}
private:
static int m_B;
};
int Phone ::m_A = 100; // 类外初始化操作
int Phone ::m_B=200;
void test01()
{
Phone p;
Phone p2;
p2.m_A = 200; // 结果变为200
cout << p.m_A << endl;
Phone::func();
cout << p.m_A << endl;
}
int main()
{
test01();
return 0;
}
对象模型和成员函数分开存储
#include <iostream>
using namespace std;
class Phone
{
};
void test01()
{
Phone p;
cout<<"size of p = "<<sizeof(p)<<endl;
}
int main()
{
test01();
return 0;
}
//size of p=1
//空对象占用内存为1;

this指针
本质是指针常量 指向是不可以更改的 指向的值是可以修改的


#include <iostream>
using namespace std;
class Phone
{
public:
int age;
Phone(int age){
this->age=age;
//this指针指的是被调用的成员函数所属的对象
}
Phone &Padd(Phone &p){//用引用的方式进行返回
this->age+=p.age;
return *this;//this指向篇p2的指针,*this指向的是p2这个对象的本体
}//返回对象本身
};
void test01()
{
Phone p1(15);
cout<<p1.age<<endl;
}
void test02(){
Phone p2(15);Phone p3(15);
p2.Padd(p3).Padd(p3).Padd(p3);//可以实现追加,就像字符串
cout<<p2.age<<endl;
}
int main()
{
test01();
test02();
return 0;
}
空指针访问成员函数
如果用到this,需要多考虑if(this==NULL){return;}
void test01()
{
Phone *p=NULL;
Phone p1(15);
p->Show(p1);
cout<<p1.m_age<<endl;
}
const修饰成员函数 加上后 函数为常函数 对象为常对象

在成员函数后面加const修饰的是this指针指向,让指针指向的值也不可以修改
#include <iostream>
using namespace std;
class Phone
{
public:
int m_A;
void show() const//==Phone *const this
{
this->m_B=100;
}
mutable int m_B;//特殊变量 加mutable可以修改
};
void test01()
{
Phone p1;
p1.show();
p1.m_B=250;
cout<<p1.m_B;//250
}
int main()
{
test01();
return 0;
}
友元

友元类
访问类中的私有成员
成员函数做友元
某类的成员函数作为本类的好朋友,可以访问
运算符重载
1.1加号运算符重载
作用:实现自定义数据类型的运算

#include <iostream>
using namespace std;
class Person
{
public:
int m_A;
int m_B;
Person operator+(Person &p){
Person temp;
temp.m_A=this->m_A+p.m_A;
temp.m_B=this->m_B+p.m_B;
return temp;
}
};
void test01()
{
Person p1;
Person p2;
p1.m_A=10;
p1.m_B=12;
p2.m_A=10;
p2.m_B=13;
Person p3;
p3=p1+p2;
cout<<p3.m_A<<endl;
}
int main()
{
test01();
return 0;
}
1.2左移运算符
#include <iostream>
using namespace std;
class Person
{
public:
int m_A;
int m_B;
};
ostream &operator<<(ostream &cout,Person &p){
cout<<p.m_A<<endl;
cout<<p.m_B<<endl;
return cout;
}
void test01()
{
Person p1;
p1.m_A=10;
p1.m_B=12;
cout<<p1<<"aisss"<<endl;
}
int main()
{
test01();
return 0;
}
1.3递增运算符重载
#include <iostream>
using namespace std;
class Myint
{
friend ostream &operator<<(ostream &cout, Myint myyint);
public:
Myint()
{
m_num=0;
}
Myint &operator++(){
m_num++;//进行++运算
return *this;//返回自身,*this
}
Myint operator++(int){//后置++运算符重载,int为占位参数,double等其他不好使
//先记录结果
Myint temp=*this;
//递增
m_num++;
//返回记录结果
return temp;
}
private:
int m_num;
};
//重载<<
ostream &operator<<(ostream &cout, Myint myyint)
{
cout<<myyint.m_num;
return cout;
}
void test01()
{
Myint p;
cout<<++(++p)<<endl;
//cout<<p<<endl;
}
void test02()
{
Myint mml;
cout<<mml++<<endl;
cout<<mml<<endl;
}
int main()
{
int a=0;
cout<<++a<<endl;
test01();
test02();
return 0;
}
运行结果:
1
2
0
1
赋值操作

#include <iostream>
using namespace std;
class Person
{
public:
Person(int age){
m_age=new int(age);
}
int *m_age;
~Person()
{
if(m_age!=NULL){
delete m_age;
m_age=NULL;
}
}
Person &operator=(Person &p)
{
//先判断是否有属性在堆区,如果有先释放干净,
if(m_age!=NULL){
delete m_age;
m_age=NULL;
}
//再深拷贝
m_age=new int(*p.m_age);
return *this;
}
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(26);
p2=p1=p3;//实现赋值的连等,需要返回自身
cout<<*p1.m_age<<endl;
cout<<*p2.m_age<<endl;
}
int main()
{
test01();
return 0;
}
重载关系运算符
#include <iostream>
using namespace std;
class Person
{
public:
Person(string name, int age){
m_name=name;
m_age=age;
}
string m_name;
int m_age;
// 重载关系运算符
bool operator==(Person &p)
{
if (this->m_name == p.m_name && this->m_age == p.m_age)
{
return true;
}
return false;
}
bool operator!=(Person &p){
if(this->m_name!=p.m_name||this->m_age!=p.m_age){
return true;
}
return false;
}
bool operator>=(Person &p){
if(this->m_age>=p.m_age){
return true;
}
return false;
}
};
void test01()
{
Person p1("aisssky", 18);
Person p2("aisssky", 18);
if(p1==p2){
cout<<"iwc"<<"磕你俩了"<<endl;
}
else if(p1!=p2){
cout<<"唉"<<endl<<"没关系"<<endl;
if(p1>=p2){
cout<<"那p1在左边吧"<<endl;
}
else{
cout<<"那p2在左边吧"<<endl;
}
}
}
int main()
{
test01();
return 0;
}
函数调用重载(仿函数)非常灵活,没有固定的写法,类似于平时调用的函数库写法
#include <iostream>
using namespace std;
class Person
{
public:
void operator()(string name){
cout<<name<<endl;
}
};
int main()
{
Person MyPrint;
MyPrint("gogogo");
return 0;
}