1.
/********* 探讨权限 ************
* 权限|位置 类外 类内 派生
* 公有: √ √ √
* 保护: × √ √
* 私有: × √ ×
* 总结:
* 类外:只能访问公有成员
* 类内:可访问所有成员
* 派生:无法访问祖先类的私有成员
*
* 注意:
* C++中权限关键字开始位置就是权限
* 直到下一个权限关键字或者类结束
* ****************************/
******************************************************
* 什么时候使用相关权限?
* 公有:一般想让外界直接访问的之后使用公有权限,类似接口函数
* 保护:既不想要外部访问,但是又想让派生类继承使用则使用保护权限
* 私有:只允许内部自己访问,派生无法访问
* ******************************************************/
2.
/********* 构造函数 和 析构函数 ***************
*构造函数:
* 作用:用于申请空间时初始化处理
* 定义:
* 1.函数名与类名相同
* 2.无返回值
* --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
*析构函数:
* 作用:用于销毁时做释放处理
* 定义:
* 1.函数名与类名相同,但多了一个~号
* 2.无参,无返回值
* --->然通过以上定义规则发现,析构函数无法重载
* 注意:
* 如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
* 1.无参构造
* 2.拷贝构造(浅)
* 3.析构函数
* 4.=运算符函数
* ******************************************/
代码:
#include
#include
using namespace std;
/********* 构造函数 和 析构函数 ***************
*构造函数:
* 作用:用于申请空间时初始化处理
* 定义:
* 1.函数名与类名相同
* 2.无返回值
* --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
*析构函数:
* 作用:用于销毁时做释放处理
* 定义:
* 1.函数名与类名相同,但多了一个~号
* 2.无参,无返回值
* --->然通过以上定义规则发现,析构函数无法重载
* 注意:
* 如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
* 1.无参构造
* 2.拷贝构造(浅)
* 3.析构函数
* 4.=运算符函数
* ******************************************/
class People
{
public:
People(); /*无参构造*/
People(string name,int age,string sex = "女"); /*带参构造*/
People(const People &people); /*拷贝构造*/
~People(); /*析构函数*/
public:
void Print() const;/*接口函数*/
void operator =(const People &people) /*=号赋值运算符*/
{
this->m_name = people.m_name;
this->m_age = people.m_age;
this->m_sex = people.m_sex;
cout << "=号赋值运算符" << endl;
}
protected:
string m_name; /*姓名*/
int m_age; /*年龄*/
string m_sex; /*性别*/
};
/***** 类外实现 *****/
People::People() /*无参构造*/
{
this->m_name = "";
this->m_age = 0;
this->m_sex = "女";
cout << "无参构造" << endl;
}
People::People(string name,int age,string sex)/*带参构造*/
{
this->m_name = name;
this->m_age = age;
this->m_sex = sex;
cout << "带参构造" << endl;
}
People::People(const People &people) /*拷贝构造*/
{
this->m_name = people.m_name;
this->m_age = people.m_age;
this->m_sex = people.m_sex;
cout << "拷贝构造" << endl;
}
People::~People() /*析构函数*/
{
cout << "析构函数" << endl;
}
void People::Print() const
{
cout << "\t姓名:" << this->m_name
<< "\t年龄:" << this->m_age
<< "\t性别:" << this->m_sex
<< endl;
}
int main()
{
/*1.实例化对象*/
People people1; /* 默认调用无参 */
People people2("张三",18,"男"); /*带参构造*/
People people3("李四",17); /*带参构造*/
People people4(people2); /*拷贝构造*/
People people5 = people2; /*拷贝构造*/
people5 = people3; /*=号赋值运算符*/
/********* 输出结果内容 **********/
cout << "\npeople1:" << endl;
people1.Print();
cout << "\npeople2:" << endl;
people2.Print();
cout << "\npeople3:" << endl;
people3.Print();
cout << "\npeople4:" << endl;
people4.Print();
cout << "\npeople5:" << endl;
people5.Print();
return 0;
}
3.
/*********** 浅拷贝 Vs 深拷贝 *************************
*浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
* 会造成:①一个操作多个对象 ②多次析构照成程序崩溃
*深拷贝: 在堆区申请空间的操作都要实现
* 注意:一般牵扯指针操作,都会自己实现深拷贝
****************************************************/
代码:
#include
#include
using namespace std;
/*********** 浅拷贝 Vs 深拷贝 *************************
*浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
* 会造成:①一个操作多个对象 ②多次析构照成程序崩溃
*深拷贝: 在堆区申请空间的操作都要实现
* 注意:一般牵扯指针操作,都会自己实现深拷贝
****************************************************/
class A{
public:
A(){cout << "A的构造函数" <a = new A; /*申请空间,修改指向*/
*this->a = *people.a;/*拷贝内容到新的空间*/
cout << "深拷贝构造函数" << endl;
}
~People()
{
delete a; /*释放*/
}
public:
A *a; /* 类成员指针 */
};
int main()
{
/***** 打印大小 *****/
cout << "sizeof(string) = " << sizeof(string) << endl;
cout << "sizeof(A) = " << sizeof(A) << endl;
cout << "sizeof(People) = " << sizeof(People) << endl;
/***** 1.实例化对象 ****/
People *people = new People;
people->a->name[0] = "张三";
People people1(*people); /* 拷贝构造 */
people1.a->name[0] = "李四";
cout << "people->a->name[0]" << people->a->name[0] << endl;
cout << "people1.a->name[0]" << people1.a->name[0] << endl;
delete people;
return 0;
}
4.
/****** 程序的执行顺序(初始化顺序) **************
* 1.自上而下
* 2.从左往右
* 总结:初始化列表不会影响正常初始化顺序
* 总结:析构顺序与初始化顺序相反
* *****************************************/
代码:
other.h
#ifndef OTHER_H
#define OTHER_H
#include
using namespace std;
class A{
public:
A(){cout << __func__<< endl;}
A(int xx){cout << __func__<< endl;}
~A(){cout << __func__<< endl;}
};
class B{
public:
B(){cout << __func__<< endl;}
B(int xx){cout << __func__<< endl;}
~B(){cout << __func__<< endl;}
};
class C{
public:
C(){cout << __func__<< endl;}
~C(){cout << __func__<< endl;}
};
class D{
public:
D(){cout << __func__<< endl;}
~D(){cout << __func__<< endl;}
};
/**** 人类中包含A和B *****/
class People : public C,public D{
public:
People()
:b(20),a(10)/*初始化列表 父类构造 -> 成员*/
{cout << __func__<< endl;}
~People(){cout << __func__<< endl;}
public:
A a;
B b;
};
class Student
{
public:
Student(string name,int age)
:m_name(name),m_age(age)
{
}
public:
string m_name;
int m_age;
};
#endif // OTHER_H
main.c
#include
#include "Other.h"
using namespace std;
/****** 程序的执行顺序(初始化顺序) **************
* 1.自上而下
* 2.从左往右
* 总结:初始化列表不会影响正常初始化顺序
* 总结:析构顺序与初始化顺序相反
* *****************************************/
int main()
{
/*1.实例化People */
People people; // C -> D -> A -> B -> People
Student stu("张三",18);
cout << stu.m_name << "\t" << stu.m_age << endl;
return 0;
}/* 调用析构: ~People -> ~B -> ~A -> ~D -> ~C */
5.
/******** 常量成员 ***************************************
* 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
* 分类:
* 常量成员属性:
* 定义:在变量名之前加 const
* 作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
* 常量成员函数:
* 定义:在函数参数后加 const
* 作用:该函数不可修改类成员属性值,只可访问
* 自己在函数中定义的变量可以修改
* 注意:一般读取函数都会写成const常函数
*
* 常对象只能访问常函数,后面set容器存放的都会变成常对象
* *****************************************************/
代码:
#include
using namespace std;
/******** 常量成员 ***************************************
* 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
* 分类:
* 常量成员属性:
* 定义:在变量名之前加 const
* 作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
* 常量成员函数:
* 定义:在函数参数后加 const
* 作用:该函数不可修改类成员属性值,只可访问
* 自己在函数中定义的变量可以修改
* 注意:一般读取函数都会写成const常函数
*
* 常对象只能访问常函数,后面set容器存放的都会变成常对象
* *****************************************************/
class People
{
public:
People():value(10)
{
}
public:
/**** 成员属性 ****/
const int value;
int m_temp;
public:
/**** 成员函数 ****/
void Print() const
{
/* 访问 */
cout << "value = " << value << endl;
cout << "m_temp = " << m_temp << endl;
/* 修改 */
//m_temp = 500;
/* 自定义函数变量可修改 */
int xxx = 10;
xxx = 50;
}
void SetTemp(int temp)
{
m_temp = temp;
}
int temp() const;
};
int main()
{
People people;
people.Print(); /* 调用 const 成员函数 */
people.SetTemp(50);/* 调用 非const 成员函数 */
const People peo;
peo.Print();/* 调用 const 成员函数 */
//peo.SetTemp(50);/* 调用 非const 成员函数 */ 报错: 常对象只能调用常函数
return 0;
}
int People::temp() const
{
return m_temp;
}
6.
/********** this 指针和空指针 *********
* 都是指向到自己的指针
* *********************************/
代码:
#include
using namespace std;
class People
{
public:
People(string name = "wu",int age = 0) : m_name(name),m_age(age){} /* 构造函数 */
void Print();
void SetValue(int value);
public:
string m_name;
int m_age;
int value; /*注意这个成员*/
};
/********** this 指针和空指针 *********
* 都是指向到自己的指针
* *********************************/
void People::Print()
{
/**** this指针案例 ****/
cout << "name = " << this->m_name << endl;
printf("this = %p\n",this);
/**** 空指针案例 : 会造成同名问题,所以使用this指针解决*****/
cout << "name = " << m_name << endl;
cout << "value = " << value << endl;
}
/** 发现类成员属性名与函数参数名重名 **/
/** 根据调用优先级规则,谁定义得近调用谁**/
void People::SetValue(int value)
{
/** 在这里设置会不产生任何效果:因为 value是栈自己定义的会随着销毁 **/
value = value;
/** 可以 使用this指针解决该问题 **/
this->value = value;
}
int main()
{
People people;
people.SetValue(500);
people.Print();
People *ptr = &people;
printf("ptr = %p\n",ptr);
return 0;
}
7.
/******** 静态成员特征 *********
* 公有特征:
* 1.可以通过对象 或 类名访问
* 2.所有对象公用同一静态变量空间
*
* 静态成员属性:
* 注意:类内声明,类外初始化
* 常用:用作数据记录
* 须知:
* 1.所有对象共享同一份数据
* 2.空间在编译阶段就已经分配
* 3.静态成员不占用对象空间
* 静态成员函数:类内声明类外实现也可以,类内实现也可以
* 注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
* 常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
*
* ***************************/
代码:
#include
#include
using namespace std;
class People
{
public:
People(){
s_value++;
}
public: /* 成员函数 */
static void GetValue() /* 静态成员函数 */
{
cout << "我是静态成员函数" << endl;
cout << "s_value = " << s_value << endl;
//cout << "m_value = " << m_value << endl; 报错:静态成员函数不能使用非静态成员
}
static string GetIP()
{
return "IPV4 192.168.1.100";
}
static int GetMax(int value1,int value2)
{
return value1 > value2 ? value1 : value2;
}
public: /* 成员属性 */
static int s_value; /*静态成员属性:类内声明,类外初始化*/
int m_value;
};
/******** 静态成员特征 *********
* 公有特征:
* 1.可以通过对象 或 类名访问
* 2.所有对象公用同一静态变量空间
*
* 静态成员属性:
* 注意:类内声明,类外初始化
* 常用:用作数据记录
* 须知:
* 1.所有对象共享同一份数据
* 2.空间在编译阶段就已经分配
* 3.静态成员不占用对象空间
* 静态成员函数:类内声明类外实现也可以,类内实现也可以
* 注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
* 常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
*
* ***************************/
/** 静态成员属性类外初始化 **/
int People::s_value = 0;
int main()
{
/* 1.实例化对象 */
//People people;
/* 2.调用对象 */
/* 2.1 实例对象调用静态成员 */
//cout << people.s_value << endl;
/* 2.2 通过类名调用静态成员 */
//cout << People::s_value << endl;
//People::GetValue();
/* 2.3 通常静态成员属性做记录数据 */
//cout << "当前女娲造人:" << People::s_value << endl;
//{People people;}
//cout << "当前女娲造人:" << People::s_value << endl;
//{People people;}
//cout << "当前女娲造人:" << People::s_value << endl;
//{People people;}
//cout << "当前女娲造人:" << People::s_value << endl;
//{People people;}
//cout << "当前女娲造人:" << People::s_value << endl;
/* 2.4 通常静态函数做接口使用 */
cout << People::GetIP() << endl;
cout << People::GetMax(10,20) << endl;
/* 2.5 静态成员不占用类空间 */
cout << "sizeof(People) = " << sizeof(People) << endl;
/* 3.销毁对象 */
return 0;
}